Question

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?

Was it helpful?

Solution

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?

OTHER TIPS

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.

def sample(a,b,*,c=0): print(a,b,c)

* -> is before argument is args and after argument is kwargs(keyword arguments)

sample(1,2,c=10) sample(a=1,b=2,c=1) # this also work sample(1,2,c) # TypeError: sample() takes 2 positional arguments but 3 were given

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top