Given a higher order function that takes multiple functions as arguments, how could that function pass key word arguments to the function arguments?
example
def eat(food='eggs', how_much=1):
print(food * how_much)
def parrot_is(state='dead'):
print("This parrot is %s." % state)
def skit(*lines, **kwargs):
for line in lines:
line(**kwargs)
skit(eat, parrot_is) # eggs \n This parrot is dead.
skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot') # error
state
is not a keyword arg of eat
so how can skit only pass keyword args relevant the function that it is calling?
Python 3.5+ allows passing multiple sets of keyword arguments ("kwargs") to a function within a single call, using the `"**"` syntax.
Use the Python **kwargs parameter to allow the function to accept a variable number of keyword arguments. Inside the function, the kwargs argument is a dictionary that contains all keyword arguments as its name-value pairs. Precede double stars ( ** ) to a dictionary argument to pass it to **kwargs parameter.
The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks ( ** ) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.
Python is pretty flexible in terms of how arguments are passed to a function. The *args and **kwargs make it easier and cleaner to handle arguments. The important parts are “*” and “**”. You can use any word instead of args and kwargs but it is the common practice to use the words args and kwargs.
You can filter the kwargs
dictionary based on func_code.co_varnames
(in python 2) of a function:
def skit(*lines, **kwargs):
for line in lines:
line(**{key: value for key, value in kwargs.iteritems()
if key in line.func_code.co_varnames})
In python 3, __code__
should be used instead of func_code
. So the function will be:
def skit(*lines, **kwargs):
for line in lines:
line(**{key: value for key, value in kwargs.iteritems()
if key in line.__code__.co_varnames})
Also see: Can you list the keyword arguments a function receives?
If you add **kwargs
to all of the definitions, you can pass the whole lot:
def eat(food='eggs', how_much=1, **kwargs):
print(food * how_much)
def parrot_is(state='dead', **kwargs):
print("This parrot is %s." % state)
def skit(*lines, **kwargs):
for line in lines:
line(**kwargs)
Anything in **kwargs
that isn't also an explicit keyword argument will just get left in kwargs
and ignored by e.g. eat
.
Example:
>>> skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot')
spamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspam
This parrot is an ex-parrot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With