Вопрос

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?

Это было полезно?

Решение

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.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top