Stephen said:
<<
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):
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.:
.... print params
....{'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 **:
{'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
.... print args
.... print kwd
....(1, 2, 3)
{}(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:
.... 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)
....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