【问题标题】:Separating **kwargs for different functions为不同的功能分离 **kwargs
【发布时间】:2014-06-19 06:17:53
【问题描述】:

给定一个接受多个函数作为参数的高阶函数,该函数如何将关键字参数传递给函数参数?

例子

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 不是 eat 的关键字 arg 那么小品如何只传递与它正在调用的函数相关的关键字 args 呢?

【问题讨论】:

  • 毫无疑问有办法做到这一点,但我认为你从错误的角度来解决这个问题。如果您的两个函数使用同名的关键字 arg,并且您想将不同的值传递给这两个函数,您会怎么做?最好只明确地传入关键字参数的字典。每个参数都可能是(比如说)一个由函数及其关键字 args 组成的二元组。
  • 这可能是最好的解决方案。

标签: python function keyword-argument


【解决方案1】:

您可以根据函数的func_code.co_varnames(在python 2中)过滤kwargs字典:

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})

在 python 3 中,应使用__code__ 而不是func_code。所以函数将是:

def skit(*lines, **kwargs):
    for line in lines:
        line(**{key: value for key, value in kwargs.iteritems() 
                if key in line.__code__.co_varnames})

另见:Can you list the keyword arguments a function receives?

【讨论】:

  • @Aशwiniचhaudhary 谢谢,好点,一如既往的有帮助。我还添加了相关主题的链接。
  • inspect.getargspec(func).args 比 line.func_code.co_varnames 有什么好处?那么检查模块是否只是提供了我们在这种情况下不需要的更多选项?
  • @ptwales inspect 真的 usesfunc_code 一样。 inspect 通常是为对象检查所涉及的“魔法”提供接口的工作工具。
【解决方案2】:

如果将**kwargs 添加到所有定义中,则可以传递全部内容:

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)

**kwargs 中任何不是显式关键字参数的内容都将留在kwargs 中并被例如忽略。 eat.

例子:

>>> skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot')
spamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspam
This parrot is an ex-parrot.

【讨论】:

    【解决方案3】:

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

    * -> 在参数之前是 args,在参数之后是 kwargs(关键字参数)

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      相关资源
      最近更新 更多