*args
和 **kwargs
是一个常见的习惯用法,允许函数使用任意数量的参数,如 more on defining functions 部分所述。在 Python 文档中。
*args
将为您提供所有函数参数as a tuple :
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, **kwargs):
pass
也可以反过来使用:
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)
l = [1,2]
foo(*l)
# 1 2
在 Python 3 中,可以在赋值 (Extended Iterable Unpacking) 的左侧使用 *l
,尽管在这种情况下它给出的是列表而不是元组:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Python 3 也增加了新的语义(引用 PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
例如,以下在 python 3 中有效,但在 python 2 中无效:
>>> x = [1, 2]
>>> [*x]
[1, 2]
>>> [*x, 3, 4]
[1, 2, 3, 4]
>>> x = {1:1, 2:2}
>>> x
{1: 1, 2: 2}
>>> {**x, 3:3, 4:4}
{1: 1, 2: 2, 3: 3, 4: 4}
这样的函数只接受 3 个位置参数,并且 *
之后的所有内容都只能作为关键字参数传递。
注意:
- 在语义上用于关键字参数传递的 Python
dict
是任意排序的。但是,在 Python 3.6 中,保证关键字参数会记住插入顺序。
- “
**kwargs
中的元素顺序现在对应于传递给函数的关键字参数的顺序。” - What’s New In Python 3.6
- 事实上,CPython 3.6 中的所有字典都会记住插入顺序作为实现细节,这在 Python 3.7 中成为标准。
我是一名优秀的程序员,十分优秀!