Single and double asterisks preceding variables in function arguments
Peter Otten
__peter__ at web.de
Mon Jan 26 17:24:04 EST 2004
Stephen Boulet wrote:
> <<
> a={'c1':'red','c2':'blue','c3':'fusia'}
> def bar(**params):
> ....for k in params.keys():
> ........print k, params[k]
> bar(a)
> Traceback (most recent call last):
> File "<input>", line 1, in ?
> TypeError: bar() takes exactly 0 arguments (1 given)
> >>
>
> Why does bar take zero arguments?
The error message is not as clear as it should should be. bar() takes 0
mandatory, 0 positional and an arbitrary number of keyword arguments, e.
g.:
>>> def bar(**params):
... print params
...
>>> bar(color="blue", rgb=(0,0,1), name="sky")
{'color': 'blue', 'rgb': (0, 0, 1), 'name': 'sky'}
That's the standard way of passing optional keyword arguments, but you can
also pass them as a dictionary preceded by **:
>>> adict = {'color': 'blue', 'rgb': (0, 0, 1), 'name': 'sky'}
>>> bar(**adict)
{'color': 'blue', 'rgb': (0, 0, 1), 'name': 'sky'}
This is useful, if you want to compose the argument dict at runtime, or pass
it through to a nested function.
>
> Hmm, but:
>
> <<
> def bar2(*params,**moreparams):
> ....print "params are ", params,'\n'
> ....for k in moreparams.keys():
> ........print k, moreparams[k]
> ....print "moreparams are ", moreparams
bar2() accepts 0 mandatory, as many positional and keyword arguments as you
like. For the expected result, try
>>> def bar2(*args, **kwd):
... print args
... print kwd
...
>>> bar2(1,2,3)
(1, 2, 3)
{}
>>> bar2(1, name="sky", color="blue")
(1,) # tuple of optional positional args
{'color': 'blue', 'name': 'sky'} # dict of optional keyword args
>>>
And now a bogus example that shows how to compose the arguments:
>>> def bar3(x, *args, **kwd):
... print "x=", x
... print "args=", args
... print "kwd=", kwd
... if "terminate" not in kwd:
... kwd["terminate"] = None # avoid infinite recursion
... bar3(x*x, *args + ("alpha",), **kwd)
...
>>> bar3(2, "beta", color="blue")
x= 2
args= ('beta',)
kwd= {'color': 'blue'}
x= 4
args= ('beta', 'alpha')
kwd= {'color': 'blue', 'terminate': None}
>>>
To further complicate the matter, a mandatory arg may also be passed as a
keyword argument:
bar3(x=2, color="blue") # will work, args is empty
bar("beta", # will not work; both "beta" and 2 would be bound to x
# and thus create a conflict
x=2, color="blue")
Peter
More information about the Python-list
mailing list