函数
定义函数
1.定义格式:
def 函数名(形参表):
'''文档字符串'''
函数体
[return[ 返回值]]
注:
函数名:是一个标识符,需符合标识符命名规则
文档字符串:用于书写函数帮助文档,可用help(函数名.__doc__)获取文档字符串
函数体:书写函数功能语句
返回值:
(1)当函数不写return语句或写return语句但没有写返回值时,默认返回None(空)
(2)当需要返回多个值时,可用列表、元组、字典进行保存
return语句作用:
(1)返回值
(2)结束函数执行
#-------------------------示例代码-------------------------------#
def add(arg1,arg2):
'''求两数之和'''
return arg1+arg2 # 函数返回表达式的结果
#----------------------------------------------------------------#
2.函数对象
函数也是对象,且是不可变对象,函数一旦定义,就在内存中分配了存储空间(只创建一次)
(1)用变量对函数进行引用
def function():
print("函数对象引用")
func1 = function
func1() # print:函数对象引用
(2)用函数对象对函数对象赋值
def func1():
print("func1")
def func2():
print("func2")
func1() # print:func1
func2() # print:func2
func1 = func2 # 对函数对象进行赋值
func1 # print:func2
func2 # print:func2
函数中的变量
按作用域分类
1.全局变量
(1)作用范围为当前定义模块,从定义位置向后的区域
(2)一般作常量使用
(3)函数内要改变全局变量值时需用global声明
2.局部变量
(1)函数中声明的变量(包含形式参数)
(2)局部变量引用优于全局变量(对于循环次数较多时,应优先考虑局部变量)
(3)局部变量与全局变量同名时,函数会优先使用局部变量
3.获取当前程序变量
(1)locals()获取字典格式的局部变量
(2)globals()获取字典格式的全局变量
#-------------------------示例代码-------------------------------#
def func():
m = 0 # 局部变量
a = 10 # 全局变量
函数参数
1.参数传递
本质:实参到形参的赋值,python一切皆对象,所有的赋值都是引用赋值,所有的参数传递都是引用传递
(1)对于可变对象(字典、列表、集合、自定义对象等)
“写操作”会改变原对象本身
(2)对于不可变对象(数字、字符串、元组、布尔值、函数等)
“写操作”会产生新对象,并用新值填充空间,起到所谓的“值传递”效果
#-------------------------示例代码-------------------------------#
def func(argv):
print("id(argv)={0}".format(id(argv)))
argv = 1
print("id(argv)={0}".format(id(argv)))
v = 10
print("id(v)={0}".format(id(v)))
func(v)
# 运行结果:
# id(v)=1736076640 v为不可变对象
# id(argv)=1736076640 赋值前,argv与v引用同一对象
# id(argv)=1736076352 赋值后,产生新对象,argv引用新对象,v不变
#----------------------------------------------------------------#
2.引申概念:浅拷贝与深拷贝
(1)copy()函数-实现浅拷贝(import copy)
对其内包含的可变子对象的修改会相互影响
(2)deepcopy()函数-实现深拷贝(import copy)
不管其内是否包含可变子对象,对可变子对象的修改都不会相互影响
(3)不可变对象的传递是浅拷贝
#-------------------------示例代码-------------------------------#
import copy
lt = [1,2,3,[4,5]]
lt1 = copy.copy(lt) # 浅拷贝
lt1[-1].append(6)
lt1.append(7)
print("lt={}".format(lt))
print("lt1={}".format(lt1))
#运行结果
# lt=[1, 2, 3, [4, 5, 6]]
# lt1=[1, 2, 3, [4, 5, 6], 7]
#----------------------------------------------------------------#
3.参数类型
(1)位置参数--传参时需按位置顺序进行传递,参数个数必须相同
(2)默认参数--定义函数时为参数设置默认值,默认参数必须放在最后,但需在可变参数之前
(4)命名参数--传参时按名字(关键字)匹配
(3)可变参数
*param -- 将多个位置参数收集到元组中
**param -- 将多个关键字参数收集到字典中,非可变参数传参格式不受影响
(5)强制命名参数--传参时可变参数后,增加新参数需强制命名
#-------------------------示例代码-------------------------------#
def func(arg1,arg2,arg3=3): # 带默认参数
pass
def func1(arg1,arg2,*arg):
pass
def func2(arg1,arg2,**arg):
pass
func(1,2,3) # 位置参数方式传参
func(1,2) # 默认参数可不传参,采用默认值
func(arg1=1,arg2=2) # 命名参数方式传参
func1(1,2,3,4,5,6) # arg = (4,5,6)
func2(1,2,3,a=4,b=5,c=6) # arg = {"a":4,"b":5,"c":6}
#----------------------------------------------------------------#
lambda表达式
1.lambda表达式:
用于声明匿名函数,实际会生成一个函数对象
2.语法:
lambda arg1,argv2,... : 表达式(只允许包含一个表达式)
注:调用lambda表达式生成的函数对象,返回表达式执行的结果
#-------------------------示例代码-------------------------------#
func = lambda a,b,c : a*b*c
value = func(1,2,3) # value = 6
eval()函数
1.功能
将字符串当成有效表达式来求值并返回计算结果,也可用于代码解析
2.语法
eval(source[,globals[,locals]])
参数:
source -- 一个python表达式或函数compile()返回的代码对象
globals -- 可选参数,必须为字典
locals -- 可选参数,任意映射对象
#-------------------------示例代码-------------------------------#
value = eval("a+b",dict(a=1,b=2)) # value = 3
eval("print('hello world')") # print: hello world
code = compile("a+b","","eval")
value = eval(code,dict(a=1,b=2)) # value = 3
递归函数
嵌套函数
嵌套函数(内部函数)--实质是函数的嵌套定义
作用:
(1)封装--外部无法访问内部函数
(2)避免函数内的重复代码
(3)闭包
注:
nonlocal关键字--用于在内部函数中声明所在函数的局部变量
global关键字--用于在函数中声明全局变量
内部函数只允许所在函数调用,无法在所在函数之外调用
#-------------------------示例代码-------------------------------#
def func1():
def func2(): # 内部函数
print("func2")
nonlocal l_v
global g_v
print(l_v)
print(g_v)
print("func1")
l_v = "local varible"
func2()
g_v = "global varible"
func1() # ok
func2() # error
# 运行结果
# func1
# func2
# local varible
# global varible
LEGB规则
python查找“名称”时按LEGB规则查找:
local ---- enclosed ---- global ---- built in
local – 函数或方法内部
enclosed – 嵌套函数(闭包)
global – 全局变量
built in – 保留字