【问题标题】:Use **kwargs both in function calling and definition在函数调用和定义中都使用 **kwargs
【发布时间】:2013-05-16 21:45:16
【问题描述】:

假设我有一个函数get_data,它接受一些关键字参数。有什么办法可以做到这一点

def get_data(arg1, **kwargs):
    print arg1, arg2, arg3, arg4

arg1 = 1
data['arg2'] = 2 
data['arg3'] = 3 
data['arg4'] = 4 

get_data(arg1, **data)

所以我们的想法是避免在函数调用和函数定义中输入参数名称。我用字典作为参数调用函数,字典的键成为函数的局部变量,它们的值是字典值

我尝试了上述方法并收到错误消息global name 'arg2' is not defined。我知道我可以更改 get_data 定义中的 locals() 以获得所需的行为。

所以我的代码看起来像这样

def get_data(arg1, kwargs):
    locals().update(kwargs)
    print arg1, arg2, arg3, arg4

arg1 = 1
data['arg2'] = 2 
data['arg3'] = 3 
data['arg4'] = 4 

get_data(arg1, data)

它也不起作用。如果不使用locals(),我也不能实现这种行为吗?

【问题讨论】:

  • 不要修改locals,甚至不能保证一直工作:docs.python.org/2/library/functions.html#locals
  • .. 你为什么要这样做?如果您知道 arg2、arg3、arg4 总是会被传递,那么您应该将它们指定为单独的参数。如果你不这样做,那么即使你有想要的行为,只要你引用了arg4data 没有定义arg4,它就会引发一个NameError。它甚至不会打印任何数据,只会引发错误。
  • @MorganWilde 我理解这个概念,但想法是避免在函数定义和函数调用中写名字
  • lovesh,在函数定义中避免使用名称是一个糟糕的概念,因为它很难理解哪些参数是必需的,哪些参数没有效果。

标签: python


【解决方案1】:

**kwargs 是一个普通的字典。试试这个:

def get_data(arg1, **kwargs):
    print arg1, kwargs['arg2'], kwargs['arg3'], kwargs['arg4']

另外,请查看keyword arguments 上的文档。

【讨论】:

    【解决方案2】:

    如果我们检查您的示例:

    def get_data(arg1, **kwargs):
        print arg1, arg2, arg3, arg4
    

    在您的get_data 函数的命名空间中,有一个名为arg1 的变量,但没有名为arg2 的变量。因此您无法访问不在您的命名空间中的函数或变量。

    事实上,在你的命名空间中;有一个变量 arg1 和一个名为 kwargsdictionary 对象。在 kwargs 之前使用 ** 表示法(名称 kwargs 在这里并不重要,它也可以是别的东西。)告诉你的 python 编译器 kwargs 是一个字典,并且该字典中的所有值都将被评估为命名参数在您的函数定义中。

    让我们看一下这个例子:

    def myFunc(**kwargs):
        do something
    
    myFunc(key1='mykey', key2=2)
    

    当您使用命名参数key1key2 调用myFunc 时,您的函数定义就像

    def myFunc(key1=None, key2=None):
    

    但是有一个例外!由于myFunc 没有命名参数,编译器不知道如何直接处理它们,因为您可以将任何命名参数传递给您的函数。

    所以你的函数接受字典中的那些命名参数,就像你调用你的函数一样:

    myFunc({key1:'mykey', key2:2})
    

    所以,您的函数定义会在字典中获取这些参数。 **kwargs 在这一点上定义了你的字典,这也告诉编译器任何命名参数都将被接受(通过 kwargs 前的** 符号的帮助)

    def myFunc(**kwargs):
        print kwargs
    

    将打印

    {key1:'mykey', key2:2}
    

    所以在你的例子中,你可以像字典一样使用kwargs

    def myFunc(**kwargs):
        kwargs['arg2']
        kwargs.get('arg3')
    

    希望不复杂(:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-30
      • 2012-04-09
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      相关资源
      最近更新 更多