函数:将一段代码定义为函数并指定函数名,方便调用
lambda表达式:可作为表达式、函数参数、函数返回值,让程序更简洁
5.1 函数入门
定义函数要考虑的3个问题
- 把动态变化的参数定义为函数的参数
- 把希望得到的数据定义为返回值
- 函数的内部实现过程
def 函数名(形参列表):
执行语句...
[return 返回值]
def 内置关键字,用于定义函数,以便将程序的各功能划分到单独的函数中
函数名:语法上,是合法的标识符即可;可读性上,应由小写单词用下划线连缀而成
形参列表:有多个形式参数时,用逗号分隔。一旦设置,调用时必须赋值
参数传递机制:为参数创建副本后传入函数——传入的是形式参数,不改变实际参数
返回值:可以是有值的变量或者表达式。既可赋值给变量,也可直接用作另一函数的参数
def my_max(x,y):
return x if x > y else y
为函数提供文档
把def之后,执行语句之前的字符串,会自动成为该函数的说明文档
调用方法:help();函数的__doc__属性
>>> def test():
'说明文档'
pass
>>> help(test)
Help on function test in module __main__:
test()
说明文档
>>> def test():
'说明文档'
pass
>>> test.__doc__
'说明文档'
多个返回值的处理与接收
Python会自动将返回值处理成元组。接收时,可以用多个变量接收返回值(序列解包功能)
>>> def test():
return 1,2
>>> test()
(1, 2)
>>> a,b = test()
>>> print(a,b)
1 2
递归函数
在函数中调用其自身,要有递归出口。
以下例子为累加程序,递归出口为【n==0】,【test(n - 1)】为调用自身
>>> def test(n):
if n == 0: return n
else: return n + test(n - 1)
>>> test(3)
6
# 5.2 函数的参数
传入(赋值)
可按位置传入,也可通过关键字传入——参数命名时应考虑语义,以便识别
>>> def test(a,b): print(a,b)
>>> test(1,2) #位置传入
1 2
>>> test(b=2,a=1) #关键字传入
1 2
设置默认值
调用时,如果有赋值,使用所赋值,否则,使用默认值
>>> def test(a=1,b=2): print(a,b)
>>> test(a=1,b=3)
1 3
参数(数量)可变
【*】+ 参数名:以元组的形式传入(按位置传入的会自动与之匹配)
【**】+ 参数名:以字典的形式传入(按关键字传入的会自动与之匹配)
一个函数最多有带【*】的参数和带【**】的参数各一个
普通参数放在可变参数之后时,普通参数一定要用关键字赋值,否则,参数名与值的对应关系不能确定
>>> def test(*a,b): print(a,b)
>>> test(1,2,b=3)
(1, 2) 3
>>> def test(*a,**b): print(a,b)
>>> test(1, 2, m=5, n=6)
(1, 2) {'m': 5, 'n': 6}
逆向参数收集
将已有的列表、元组、字典的元素拆开,传递给函数的参数
【*】 + 列表、元组
>>> def test(a,b): print(a,b)
>>> L=[1,2]
>>> test(*L)
1 2
【**】 + 字典
>>> def test(a,b): print(a,b)
>>> D = {'a':1, 'b':2}
>>> test(**D)
1 2
带可变参数
>>> def test(a,*b): print(a,b)
>>> L = [1,2,3]
>>> test(*L)
1 (2, 3)
变量作用域与变量字典
局部变量:函数内部的参数、变量,离开函数后不可访问
全局变量:函数外、全局范围内的变量,在所有函数内均可访问
变量名与变量值相当于字典的key与value,用python内置函数可获得指定范围内的变量字典
函数 | 范围 | 备注 |
---|---|---|
globals() | 全局 | 无论在哪,总是获取全局变量 |
locals() | 当前局部 | 若在全局范围中(局部之外),等效于globals() |
vars(object) | 指定对象 | 不设置object时,等效于locals() |
区别:globals(),locals()可修改全局变量;locals()修改局部变量不会报错,但也不会生效
变量被【遮蔽】的解决方法
局部变量与全局变量重名时,局部变量会【遮蔽】全局变量,导致程序报错
原因:在函数内访问变量时,如果没有提前指定,默认访问该函数的内部变量
>>> a = 1
>>> def test():
print(a)
a = 2
>>> test()
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
test()
File "<pyshell#36>", line 2, in test
print(a)
UnboundLocalError: local variable 'a' referenced before assignment
解决方法1 直接访问全局变量 globals()[key]
直接访问全局变量,并不改变全局变量
>>> a = 1
>>> def test():
print(globals()['a'])
a = 2
>>> test()
1
>>> a
1
解决方法2 声明全局变量 global key
声明全局变量后,后续操作是对全局变量赋值,会改变全局变量
>>> a = 1
>>> def test():
global a
print(a)
a = 2
>>> test()
1
>>> a
2
5.3 局部函数
对外部是隐藏的,只在其封闭函数内有效
def 函数1():
def 函数2(): #局部函数(封闭函数、子函数)
...
return 函数2 #可在函数1内返回封闭函数,以便后期调用,否则,后期无法调用
nonlocal
封闭函数内的变量名也会遮蔽函数内的变量名,此时需要用【nonlocal】声明变量
nonlocal:声明访问对象为本函数外层的变量——不是封闭函数内的变量,也不是全局变量
>>> def test1():
a = 1
def test2():
nonlocal a
print(a)
a = 2
test2()
print(a)
>>> test1()
1
2
# 5.4 函数的高级内容
-
将函数本身赋值给变量——所有函数都是function对象
作用:同一变量名在不同的时间或条件下,可以指向不同函数,使程序更灵活 -
以函数作为参数
>>> def test1(args): test2()
>>> def test2(): print(0)
>>> test1(test2)
0
- 以函数为返回值
def 函数1():
def 函数2():
...
return 函数2 #以函数2作为返回值
# 5.5 用lambda表达式代替局部函数
lambda表达式:【lambda 参数 : 表达式】,本质上是匿名的、单行的函数
lambda:python内置关键字
参数:可以省略,如果超过1 个,用【,】分隔
表达式:返回的值
以下两行代码有着相同的效果:
def test(x): return x
lambda x:x