内容来自 DOC https://q.houxu6.top/?s=**(双星号/星号)和 *(星号/星号)对参数有什么作用?
在以下函数定义中,*args
和 **kwargs
分别表示什么意思?
def foo(x, y, *args):
pass
def bar(x, y, **kwargs):
pass
关于参数的补充问题,可以参考 What do ** (double star/asterisk) and * (star/asterisk) mean in a function call?。
*args
和 **kwargs
是常见的用法,允许在函数中接受任意数量的参数,正如 Python 教程中的 关于定义函数的更多内容 一节所描述。
*args
将给你所有位置参数作为元组:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1, 2, 3)
# 1
# 2
# 3
**kwargs
将给你所有的关键字参数作为字典:
def bar(*\*kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
这两种习惯用法可以混合使用常规参数和一些可变参数:
def foo(kind, \*args, bar=None, \*\*kwargs):
print(kind, args, bar, kwargs)
foo(123, 'a', 'b', apple='red')
# 123 ('a', 'b') None {'apple': 'red'}
反过来也是可行的:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100, **obj)
# 100 10 lee
另一种使用 *l
的习惯用法是在调用函数时解包参数列表。
def foo(bar, lee):
print(bar, lee)
baz = [1, 2]
foo(*baz)
# 1 2
在 Python 3 中,可以在左侧使用 *l
(扩展迭代器解包),但在这种情况下会给出列表而不是元组:
first, *rest = [1, 2, 3, 4]
# first = 1
# rest = [2, 3, 4]
另外,Python 3 添加了一个新的语义(参见 PEP 3102):
def func(arg1, arg2, arg3, \*, kwarg1, kwarg2):
pass
这样的函数只接受前三个位置参数,*
之后的所有内容只能作为关键字参数传递。
注意:
Python 的 dict
语义上用于关键字参数传递,但是它们的顺序是任意的。然而,在 Python 3.6+ 中,关键字参数保证记住插入顺序。实际上,CPython 3.6 中的所有 dict
都会以实现细节的形式记住插入顺序,这在 Python 3.7 中成为标准。