一、定义
将部分语句放到一个区域,使用时调用次区域名称。
1、def
def 函数名称(参数列表):,多个参数用逗号相隔,没有则置空。
2、return
return [表达式],表示函数返回该表达式,一旦执行到return语句,此次函数执行已经完毕。
3、调用
无参数函数,直接使用 函数名称() 形式调用。有参数函数使用 函数名称(参数1,参数2等) 形式调用
若存在return ,需要使用变量接收返回值,无 return ,默认为 None。
二、参数
1、参数传递方式
参数分为 实参 和 形参 ,传参分为 位置传参 和 关键字传参 。
当位置传参与关键字传参并存时,需要注意位置优先级高于关键字且需要关键字传参在右(若存在函数(a,b,c)三个参数,若写(c=2,1,2)、(1,b=2,2)会报错,若是(1,2,c=2)不会报错)
2、参数类型
2.1、缺省参数
def 函数名称(a,b=1,c=1),必须从右向左依次存在,当b和c未传递时默认为1。
2.2、位置形参
将需要传递内容按照函数定义的参数位置进行放置(若函数定义为(a,b,c,d)四个参数,那传递时,默认第一个元素为a,第二个为b形式
2.3、星号元组传参
一般为 *args ,顾名思义其用法与元组一样,将多个用逗号隔开的参数包装成元组进行传递。
def func(*args): print(f"{args}") func() # () func(1, 2, 3)#(1, 2, 3)
值得注意的是,当你只传递一个参数时,*args会处理为一个元素和一个逗号的元组,所以在使用时得按照元组的方式使用(用括号在嵌套一层也会被认为一个元组作为第一个元素)
2.4、关键字形参
传递形式为 (a=1,b=2),位置可以互换,无先后之分。
2.5、双星号字典形参
一般为 **kwsrgs ,同星号元组传参,传递内容变更为字典这样的复杂类型。
def func(**kwargs): print(kwargs) # {'name': 'tarena', 'age': 18}-->kwargs func(a=1,b=2) #{'a': 1, 'b': 2}
2.6、混合使用
优先级:位置传参>星号元组形参>命名关键字参数>双星号字典形参
星号和双星号传参对参数个数无要求
三、匿名函数
使用 lambda
关键字来创建(一行): lambda [函数的参数列表]: 表达式 例如:
add = lambda x, y: x + y print(add(3, 4))
四、可变和不可变
不可变:整数、、布尔值、空值、字符串、元组等;
可变:列表、字典、集合。
五、变量作用域
变量作用域是 变量被声明后,在哪里能够被访问使用。
1、局部变量与全局变量
局部变量:定义在函数内变量,不能在函数外面使用,那么函数便是该变量的作用域,该变量也是局部变量(局部变量在函数被调用时生效,调用结束自动销毁)。
全局变量:函数内外都可以访问的变量(调用可以,若是赋值语句等改变该值的方式,则默认创建一个相同名称的局部变量);不可变类型作为全局变量在局部中不可改变,只能使用,而可变类型没有限制。
2、局部作用域修改全局变量
关键字 global ,在局部需要修改全部变量时,使用 global 变量名称 声明这是一个全局变量,可以进行修改了,而不是直接创建了同一个名字的局部变量。
3、局部作用域修改外部变量(非全局)
关键字nonlocal,在两层函数下,里层函数需要修改外层变量,使用 nonlocal 变量名称 声明。
若是多层嵌套下来发现存在重复名称的变量,那么其寻找的逻辑为 LEGB (local -> enclosin(local -> enclosing -> clobal -> built-in ),就是从本地作用域查找、外层函数作用域查找、全局作用域查找、内建作用域(python预定义)。
六、内存分配
函数调用时,内存开辟栈帧,用来存放函数变量,在调用完成后,栈帧释放。
七、递归(函数自调)
递归要求:递归界限(达到某个条件,结束递归)
def factorial(n): result = 1 i = 1 while i <= n: result *= i i+=1 return result print("factorial: ", factorial(5))