What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
在下面的方法定义中, *
和**
对param2
做了什么?
def foo(param1, *param2):
def bar(param1, **param2):
The *args
and **kwargs
is a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the Python documentation.
The *args
will give you all function parameters as a tuple:
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
The **kwargs
will give you all keyword arguments except for those corresponding to a formal parameter as a dictionary.
In [5]: def bar(**kwargs):
...: for a in kwargs:
...: print a, kwargs[a]
...:
...:
In [6]: bar(name='one', age=27)
age 27
name one
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, **kwargs):
pass
Another usage of the *l
idiom is to unpack argument lists when calling a function.
In [9]: def foo(bar, lee):
...: print bar, lee
...:
...:
In [10]: l = [1,2]
In [11]: foo(*l)
1 2
In Python 3 it is possible to use *l
on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Also Python 3 adds new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
Such function accepts only 3 positional arguments, and everything after *
can only be passed as keyword arguments.
It's also worth noting that you can use *
and **
when calling functions as well. This is a shortcut that allows you to pass multiple arguments to a function directly using either a list/tuple or a dictionary. For example, if you have the following function:
def foo(x,y,z):
print("x=" + str(x))
print("y=" + str(y))
print("z=" + str(z))
You can do things like:
>>> 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
Note: The keys in mydict
have to be named exactly like the parameters of function foo
. Otherwise it will throw a 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'
The single * means that there can be any number of extra positional arguments. foo()
can be invoked like foo(1,2,3,4,5)
. In the body of foo() param2 is a sequence containing 2-5.
The double ** means there can be any number of extra named parameters. bar()
can be invoked like bar(1, a=2, b=3)
. In the body of bar() param2 is a dictionary containing {'a':2, 'b':3 }
With the following code:
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)
the output is
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
链接地址: http://www.djcxy.com/p/164.html
上一篇: 在C#中使用的yield关键字是什么?