函数的参数
在定义Python函数时可定义形参,这些参数在调用时候才能确定具体的值,由函数的调用者负责为行参传入参数值
函数的参数类型
一、 位置参数
也叫必传参数,顺序参数,是最重要的,也是必须在调用函数时明确提供的参数!位置参数必须按先后顺序,一一对应,个数不多不少的传递!
说明:a,b,c是函数add的行参,没有具体的值,只有在add(x,y,z)是才被传入值,a=x=1,b=y=2,c=z=3, 其中x,y,z叫做实参,add(4,5,6,7),add(5,7)均为错误调用
二、关键字参数
在调用函数的时候,传递的参数是根据参数名传值,不必按照定义形参的顺序传递的参数叫做关键字参数
说明:在出传递参数时明确指定a=1,c=10,b=3,这样传递这三个变量先后顺序可以随意调换,add(0, 3, c=10)中,既有位置参数又有关键字参数,位置参数必须放到关键字参数前面否则报错
三、默认参数
在定义函数的时候,如果给某个参数提供一个默认值,这个参数就变成了默认参数,不再是位置参数了。在调用函数的时候,我们可以给默认参数传递一个自定义的值,也可以使用默认值。
说明:add( 0, 3 )没有给c传值,使用默认传值3
- 默认参数必须在位置参数后面!
def add(c=2, a, b):此种定义函数的方法是错误的
- 默认参数尽量指向不变的对象!
说明:上面的答案可能与你想的不一样,为什么呢?应为在定义默认函数时,a 为一个可变变量,在函数体被读入内存的时候,默认参数a指向的空列表对象就会被创建,a的内存地址不变,每次调用函数都像a变量中添加A
动态参数
定义: 顾名思义,就是参数的个数是可以变的,这样在调用函数的时候可以传入任意多个参数 动态参数的两种方式: 1.*args:一个星号表示接收任意个参数。调用时,会将实际参数打包成一个元组传入形式参数。如果传递的是列表,列表将被当做一个整体 2.**kwargs:两个星表示接受键值对的动态参数,数量任意。调用的时候会将实际参数打包成字典 .*args和**kwargs是约定俗成的参数名称,也可以随便写成其他任何符合命名规范的参数名称
*args:举例子**
def test(*books):
print(books)
for i in books:
print(i)
books = [ "西游记", "三国演义", "水浒传" ]
test("西游记", "三国演义", "水浒传" )
test(books)
输出结果
('西游记', '三国演义', '水浒传')
西游记
三国演义
水浒传
(['西游记', '三国演义', '水浒传'],)
['西游记', '三国演义', '水浒传']
说明:上边的例子中*books为定义的一个可变参数,调用函数的时候可以传递多个参数,print(books)可以查看数此参数为一个元组,books列表被当做一个整体传入
问题:能不能让列表它内部的('西游记', '三国演义', '水浒传')分别当做参数传递进去
答案:当然可以,就是在传递列表参数的时候在前面添加一个星号
def test(*books):
print(books)
for i in books:
print(i)
books = [ "西游记", "三国演义", "水浒传" ]
test(books)
结果:
(['西游记', '三国演义', '水浒传'])
西游记
三国演义
水浒传
** kwargs:举例说明
def func(**kwargs):
print(type(kwargs))
for kwg in kwargs:
print(kwg, kwargs[kwg])
func(k1='v1', k2=[0, 1, 2])
输出结果:
<class 'dict'>
k1 v1
k2 [0, 1, 2]
思考一下代码结果是什么:
def func(**kwargs):
print(type(kwargs))
for kwg in kwargs:
print(kwg, kwargs[kwg])
core = {
"语文": 81,
"数学": 92
}
func(core)
结果:
D:\project\test\venv\Scripts\python.exe D:/project/test/venv/monster.py
Traceback (most recent call last):
File "D:/project/test/venv/monster.py", line 87, in <module>
func(core)
TypeError: func() takes 0 positional arguments but 1 was given
Process finished with exit code 1
分析:
由于**kwargs需要传递键值对的参数,虽然字典是键值对的值,但是单独传递字典名的时候会将字典当做位置参数传递,那有什么办法将字典以键值对的方式当做多个参数传递呢?
答案:在传递字典的前面添加两个星号
func(**core)
正确结果:
<class 'dict'>
语文 81
数学 92