函数的参数传递
不可变对象
number, string, turple
函数传参如果传递的是这种类型,无法在函数内改变传入的参数的值
可变对象
list, dict, set
函数传参如果传递的是这种类型,可以在函数内改变传入的参数的值
1 | def fun(a): # a形参 |
在 Python 中,整数是不可变的(immutable),所以在 add
函数中,执行 num += 10
时,实际上是创建了一个新的整数对象,并将 num
重新指向这个新对象。这并不会影响到函数外部的 num
变量
关键字参数:**args
允许函数调用时参数顺序和定义时不一致
1 | def get_stu_info(name,age,**args): |
默认参数
调用函数时,缺省参数的值如果没有传入,则会被认为是默认值
不定长参数
加了一个*号的变量args会存放所有未命名的变量参数,----》元祖 加了**号,存放所有命名的变量参数----》字典
加了一个*号的变量args会存放所有未命名的变量参数,----》元祖 加了**号,存放所有命名的变量参数----》字典
1 | def fun(a,b,c,*args,**kwargs): |
output
1 | a= 1 |
先后顺序方面一般先*再**
匿名函数
定义:
不使用def这样语句来定义函数 使用lambda来创建一个匿名函数
1 | lambda arguments: expression |
lambda
: 关键字,表示定义一个匿名函数。arguments
: 参数列表,类似于函数的参数,但不能包含默认值、可变参数等。expression
: 单一的表达式,函数的返回值。
应用
作为参数进行传递
1 | def test(a,b,opt): #opt当做参数传递 |
output
1 | 10 |
作为内置函数的参数
1 | stus = [ |
sort 函数接受一个关键字参数 key,这个参数是一个函数或 lambda 表达式,用于指定排序的依据。
lambda y: y['name'] 是一个匿名函数,接受一个字典 y,返回该字典中键为 'name' 的值
1 | 排序之前的数据: |
偏函数
函数在执行时,要带上所有必要的参数进行调用。但是,有时参数可以在函数被调用之前提前获知。这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调用。
可以有效冻结一些预先定义好的参数,对函数参数做缓存,后面想使用再解冻 类似斐波那契数列,知道了前面的几个数,就能推导出后面的数字 比如定义了一个函数,传了2个参数,现在调用可能只会用到部分参数,可以将它冻结起来 后面想使用时候随时解冻
1 | from functools import partial |
使用了 Python 中的 functools.partial
函数来创建一个偏函数
定义了一个原始函数 add(a, b)
,用于计算两个数之和。
使用 functools.partial
创建了一个新的函数
plus
,通过 partial(add, 100)
,将原始函数
add
的第一个参数 a
固定为
100
,这样,plus
函数实际上就是
add
函数的一个变体,其中第一个参数已经被固定为
100
。
调用 plus(9)
,相当于调用
add(100, 9)
,得到结果 109
。
局部变量和全局变量
如何在函数里修改全局变量:global 全局变量名
1 | x = 10 |
1 | before function:10 |
当不可变的数据类型作为全局变量,需要用global声明,进行修改 可变的数据类型 不一定
如何在函数里使用外层变量:nonlocal 外层变量名
1 | #nonlocal:使用函数的外层变量 |
装饰器
定义:
本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。
这么做目的是:首先把函数传递到装饰器里面,先验证权限,验证通过,再调用传递进来函数
基本格式
@函数名
举例说明
定义一种装饰器函数如下
1 | def w1(fun): |
定义带装饰器的函数
1 |
|
直接调用装饰器
1 | print("直接调用装饰器") |
输出
1 | f1 |
使用被语法糖修饰的带装饰器的函数
1 | f1() |
输出
1 | f1 |
举例运用
1 | #定义了一个装饰器函数 |
输出
1 | <b>hello-world-1</b> |