瀋凣

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)
(1234567)

*加了星号 * 的参数会以元组(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 1in <module>
TypeError: myfunc() missing 2 required keyword-only arguments: 'x' and 'y'
>>> myfunc(1,2,3,x=4,y=5)
(1234 5

Deja-vu?

“逮虾户”
“逮虾户”

我们上节课最后学习的冷门小知识讲到,参数中加入*使其右侧参数只能用关键字参数传递。

>>> def abc(a,*,b,c):
...     print(a,b,c)
... 
>>> abc(1,2,3)
Traceback (most recent call last):
  File "<stdin>", line 1in <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 1in <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 (234) {'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)
(1234 {'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 1in <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
点点关注不迷路
点点关注不迷路
- END -

分类:

后端

标签:

Python

作者介绍

瀋凣
V1