[TOC]

*与**的用法

常规用法

python函数传递参数的方式有两种:

位置参数(positional argument)
关键词参数(keyword argument)
*args 与 **kwargs 的区别,两者都是 python 中的可变参数:

args 表示任何多个无名参数,它本质是一个 tuple
\
*kwargs 表示关键字参数,它本质上是一个 dict
如果同时使用 args 和 \*kwargs 时,必须 args 参数列要在 \*kwargs 之前。

在这个例子中,rest是由所有其他位置参数组成的元组。然后我们在代码中把它当成了一个序列来进行后续的计算。

1
2
3
4
5
6
7
8
def avg(first,*rest):
print('first is{}, rest is{}'.format(first,rest))
if __name__ == "__main__":
avg(1,2)
avg(1,2,3,4)
输出:
first is1, rest is(2,)
first is1, rest is(2, 3, 4)

下面这个函数时,所有位置参数会被放到args元组中,所有关键字参数会被放到字典kwargs中。

1
2
3
4
5
6
7
8
def anyargs(*args, **kwargs):
print(args) # A tuple
print(kwargs) # A dict

anyargs(1,2,3,name='qin',gender='man')
输出:
(1, 2, 3)
{'name': 'qin', 'gender': 'man'}

另外!只接受关键字参数

将要强制关键字参数放到某个*参数或者单个*后面就能达到这种效果。比如:

1
2
3
4
5
6
def recv(maxsize, *, block):
'Receives a message'
pass

recv(1024, True) # TypeError
recv(1024, block=True) # Ok

为了可读性:

1
2
3
4
5
msg=recv(1024,False)
msg=recv(1024,block=False)

def recv(maxsize,*,block):
pass

当然后者的使用方式更好了

实例!

1
2
3
4
5
for k_, v_ in kwargs.items():
setattr(opt, k_, v_)
'''
将对象opt的属性k_改变为v_,这是一个很实用的写法!!!!!
'''

函数注解

所谓注解,自然是区分于上述的强制约束参数类型。

1
2
def add(x:int, y:int) -> int:
return x + y

:int用在参数

->int用在返回值

使用__annotations__属性可获得注解字典,如果存在返回值注解,则字典中有return这个key,故参数不能用return命名。

1
2
>>>(add.__annotations__)
{'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}