函数 --- 为了代码最大程度复用和最小化代码冗余而提供的最基本程序结构
函数作用
- 最大化代码重用和最小化代码冗余
- 流程分解
def创建一个函数对象,并将其赋值给变量名;
- lambda创建一个对象但其作为结果返回;
- return将一个结果对象发送至调用者;
- yield向调用者发回结果对象,但是记住它离开的地方;
def在运行时评估,def之中代码在函数调用后才会评估。
作用域(变量定义以及查找的地方)
一个变量的作用域总是由在代码中被赋值的地方所决定的。
作用域法则
- 内嵌的模块是全局作用域;
- 全局作用域的作用范围仅限单个文件;
- 每次对函数的调用创建了新的本地作用域;
- 函数内部赋值变量(修改变量不是赋值)默认均为本地变量(包括=,import,def,函数参数名等);
- 所有未在函数内部定义的变量可分为一定范围内的 全局变量,本地或内置。
变量名解析:LEGB原则
- L:Local 本地
- E:Enclosing 函数内部/内嵌函数之间
- G:Global 全局
- B:Build-in 内置(存在于内置模块__buildin__中,可导入后使用dir()查看内置变量名)
工厂函数:返回嵌套函数的函数。
nonlocal(可以修改嵌套作用域变量)和global均限制变量的作用域查找范围。
参数传递
- 参数传递是通过自动将对象赋值给本地变量名来实现(指针引用,不会自动进行拷贝);
- 函数内部参数名赋值不影响调用者;
- 改变函数可变对象参数也许会影响调用者;
参数匹配模型
- 位置:从左至右
- 关键字参数:通过参数名
- 默认参数:定义没有传入值的默认参数
- 可变参数:收集任意多基于位置或关键字的参数
- 可变参数解包:传递任意多的基于位置或关键字的参数
- Keyword-only参数:参数按照名称传递
函数定义
def func(value1, name=value2, *seq, Name=Value(key-only), **dict)
函数调用
func(value1, value(name=value), Name=Value, *seq_value, **Dict)
示例:
def f(a, *b, c=6, **d): print(a, b, c, d)
Sample1:
f(1, 2, 3, x=4, y=5)
-> 1 (2, 3) 6 {'x': 4, 'y':5}
Sample2:
f(1, *(2, 3), **dict(x=4, y=5))
-> 1 (2, 3) 6 {'x': 4, 'y':5}
Sample3:
f(1, *(2, 3), c=7, **dict(x=4, y=5))
-> 1 (2, 3) 7 {'x': 4, 'y':5}
Sample4:
f(1, c=7, *(2, 3), **dict(x=4, y=5))
-> 1 (2, 3) 7 {'x': 4, 'y':5}