*(双星号/星号)和(星号/星号)对参数有什么作用?
时间:2020-03-05 18:45:40 来源:igfitidea点击:
在以下方法定义中," *"和" **"对" param2"有何作用?
def foo(param1, *param2): def bar(param1, **param2):
解决方案
回答
从Python文档中:
If there are more positional arguments than there are formal parameter slots, a TypeError exception is raised, unless a formal parameter using the syntax "*identifier" is present; in this case, that formal parameter receives a tuple containing the excess positional arguments (or an empty tuple if there were no excess positional arguments). If any keyword argument does not correspond to a formal parameter name, a TypeError exception is raised, unless a formal parameter using the syntax "**identifier" is present; in this case, that formal parameter receives a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary if there were no excess keyword arguments.
回答
* args
和** kwargs
是一个常见的习惯用法,它允许对函数使用任意数量的参数,如在Python文档中有关定义函数的小节中所述。
* args
将为我们提供所有函数参数作为元组:
In [1]: def foo(*args): ...: for a in args: ...: print a ...: ...: In [2]: foo(1) 1 In [4]: foo(1,2,3) 1 2 3
** kwargs
会给你所有人
关键字参数(与形式参数对应的字典除外)。
In [5]: def bar(**kwargs): ...: for a in kwargs: ...: print a, kwargs[a] ...: ...: In [6]: bar(name='one', age=27) age 27 name one
这两个习惯用法都可以与普通参数混合使用,以允许使用一组固定参数和一些可变参数:
def foo(kind, *args, **kwargs): pass
- l惯用法的另一种用法是在调用函数时解压缩参数列表。
In [9]: def foo(bar, lee): ...: print bar, lee ...: ...: In [10]: l = [1,2] In [11]: foo(*l) 1 2
在Python 3中,可以在赋值的左侧使用" * 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
该函数仅接受3个位置参数,而*之后的所有内容只能作为关键字参数传递。
回答
单个*表示可以有任意数量的额外位置参数。可以像foo(1,2,3,4,5)一样调用foo()。在foo()主体中,param2是一个包含2-5的序列。
双**表示可以有任意数量的额外命名参数。 bar()可以像bar(1,a = 2,b = 3)一样被调用。在bar()的主体中,param2是一个包含{'a':2,'b':3}的字典。
使用以下代码:
def foo(param1, *param2): print param1 print param2 def bar(param1, **param2): print param1 print param2 foo(1,2,3,4,5) bar(1,a=2,b=3)
输出是
1 (2, 3, 4, 5) 1 {'a': 2, 'b': 3}
回答
还值得注意的是,在调用函数时也可以使用*和**。这是一个快捷方式,允许我们使用列表/元组或者字典将多个参数直接传递给函数。例如,如果我们具有以下功能:
def foo(x,y,z): print("x=" + str(x)) print("y=" + str(y)) print("z=" + str(z))
我们可以执行以下操作:
>>> mylist = [1,2,3] >>> foo(*mylist) x=1 y=2 z=3 >>> mydict = {'x':1,'y':2,'z':3} >>> foo(**mydict) x=1 y=2 z=3 >>> mytuple = (1, 2, 3) >>> foo(*mytuple) x=1 y=2 z=3
注意:mydict
中的键必须完全像函数foo
的参数一样命名。否则将抛出TypeError
:
>>> mydict = {'x':1,'y':2,'z':3,'badnews':9} >>> foo(**mydict) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() got an unexpected keyword argument 'badnews'