瀋凣
V1
2022/03/03阅读:35主题:极简黑
python笔记36
Python day36
1. 函数
1.4 参数的研究
1.4.5 不定长参数(收集参数)
有些函数可以传入无限多个参数。
>>> print('hello')
hello
>>> print('hello','python','BAMF')
hello python BAMF
这些参数不可能在自定义函数时就全部创建好,那它是怎么做到的呢?
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。
定义不定长参数,只需要在形参前加上*
即可。
>>> def myfunc(*args):
... print(f"have {len(args)} elements") #通过len()获取长度
... print(f"the second element is {args[1]}") #通过下标获取元素
...
>>> myfunc(1,2,3,4,5,6,7,8)
have 8 elements
the second element is 2
为什么呢?这是怎么做到的呢?我们不妨直接打印这个不定长参数试一试:
>>> def myfunc(*args):
... print(args)
...
>>> myfunc(1,2,3,4,5,6,7)
(1, 2, 3, 4, 5, 6, 7)
*加了星号 *
的参数会以元组(tuple
)的形式导入,存放所有未命名的变量参数。
如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。
>>> def printinfo(arg,*vartuple):
... print(arg)
... for i in vartuple:
... print(i)
...
>>> printinfo(10) #只传递1个参数给 arg
10
>>> printinfo(10,20,30,40) #传递4个参数,分别给 arg 和 vartuple
10
20
30
40
如果在不定长参数后面指定其他参数,则在调用时必须使用关键字参数。
>>> def myfunc(*args,x,y):
... print(args,x,y)
...
>>> myfunc(1,2,3,4,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: myfunc() missing 2 required keyword-only arguments: 'x' and 'y'
>>> myfunc(1,2,3,x=4,y=5)
(1, 2, 3) 4 5
Deja-vu?

我们上节课最后学习的冷门小知识讲到,参数中加入*
使其右侧参数只能用关键字参数传递。
>>> def abc(a,*,b,c):
... print(a,b,c)
...
>>> abc(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: abc() takes 1 positional argument but 3 were given
>>> abc(1,b=2,c=3)
1 2 3
事实上这个*
本质上是一个匿名的不定长参数。
不定长参数除了可以将参数打包成元组,还可以将参数打包成字典:方法就是参数带两个星号 **
>>> def myfunc(**kwargs):
... print(kwargs)
...
-
此时调用此函数必须使用关键字参数,否则报错
>>> myfunc(1,2,3) #报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: myfunc() takes 0 positional arguments but 3 were given
>>> myfunc(a=1,b=2,c=3) #正确
{'a': 1, 'b': 2, 'c': 3}
当**
参数和其他参数混合使用时,**
参数必须在最后:
>>> def myfunc(**a,b):
File "<stdin>", line 1
def myfunc(**a,b):
^
SyntaxError: invalid syntax
>>> def myfunc(**a,*b):
File "<stdin>", line 1
def myfunc(**a,*b):
^
SyntaxError: invalid syntax
>>> def myfunc(a,**b):
... print(a,b)
...
>>> def myfunc(*a,**b):
... print(a,b)
...
>>>
当多重参数混合使用,形式变得更加灵活:
>>> def myfunc(a,*b,**c):
... print(a,b,c)
...
>>> myfunc(1,2,3,4,x=5,y=6,z=7)
1 (2, 3, 4) {'x': 5, 'y': 6, 'z': 7}
>>> def myfunc(*a,b,**c):
... print(a,b,c)
...
>>> myfunc(1,2,3,b=4,x=5,y=6,z=7)
(1, 2, 3) 4 {'x': 5, 'y': 6, 'z': 7}
解包参数
当*
用在形参上,起到将参数打包成元组的效果,而*
用在实参上,起到的效果则完全相反,变成了解包的效果。
>>> args = (1,2,3,4)
>>> def myfunc(a,b,c,d):
... print(a,b,c,d)
...
>>> myfunc(args) #报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: myfunc() missing 3 required positional arguments: 'b', 'c', and 'd'
>>> myfunc(*args)
1 2 3 4
同样,想要解包字典参数,只需在实参前加上**
即可。
>>> kwargs = {'a':1,'b':2,'c':3,'d':4}
>>> myfunc(**kwargs)
1 2 3 4

作者介绍
瀋凣
V1