Python: 自动将所有函数参数放入**kwargs

Python: put all function arguments into **kwargs automatically

描述

假设我有以下函数,它调用另一个函数:

def f1(arg1, arg2, arg3):
    f2(...)

f1f2的参数相同,或者f2可能是这样的:

def f2(**kwargs)
    pass  # whatever

客户端代码要定义并调用f1,要求f1的签名显式定义所有参数,因此不允许**kwargsf1.

因此,要从 f1 内部调用 f2,我必须这样做:

def f1(arg1, arg2, arg3):
    f2(arg1, arg2, arg3)

问题

有没有一种方法可以在不显式写入参数的情况下将参数传递给 f2?理想情况下,我认为它应该是这样的:

def f1(arg1, arg2, arg3):
        kwargs = <Some Magic Here>
        f2(**kwargs)

有魔法吗?

更新

可能的解决方案

有什么方法可以结合 locals()inspect.getargspec() 来聚合我的 **kwargs

一般

好吧,您可以创建 kwargs 作为 f2() 接受并传递的所有参数的字典。虽然我没有看到任何好处,但使用 -

def f1(arg1, arg2, arg3):
    f2(arg1=arg1, arg2=arg2, arg3=arg3)

我觉得不错,而且比构建字典并将其命名为 **kwargs 更容易。

无论如何,方法是 -

>>> def a(a,b,c):
...     kwargs = {'a':a , 'b':b , 'c':c}
...     d(**kwargs)
...
>>> def d(**kwargs):
...     print(kwargs)
...
>>> a(1,2,3)
{'c': 3, 'a': 1, 'b': 2}

针对您的用例

The problem is that f1 is going to be defined by the client, the processing of argument is common for all, so I want to hide the processing details, so that the client passes all the arguments to the implementation. Furthermore, I want to ease the definition and automatically pass all arguments and not specify them explicitly.

locals() 函数里面 returns 你把当时函数里局部变量的副本当作字典。如果在您的问题中 f1()f2() 的定义相同,您可以使用 locals() ,方法是在函数的开头在任何其他代码之前调用它。示例 -

>>> def a(a,b,c):
...     lcl = locals()
...     print(lcl)
...     d(**lcl)
...     e = 123
...     print(locals())
...
>>> def d(**kwargs):
...     print(kwargs)
...
>>> a(1,2,3)
{'c': 3, 'a': 1, 'b': 2}
{'c': 3, 'a': 1, 'b': 2}
{'c': 3, 'a': 1, 'e': 123, 'lcl': {...}, 'b': 2}

你在这里想要的是将父函数的参数传递给一个封闭的 function.So 拳头我必须说你不能使用 local() 因为 local 包含局部变量它包含参数和您在函数伙伴中定义的所有局部变量,但是如果您只想在动态参数时获取所有参数并且像您的示例一样,我建议在 parents 函数中使用 *args

def f1(*args):

但是这里有一点,因为你想使用 **kwargs 并且它是为了收集任意关键字参数,你需要为你的参数的初始名称。

例如,您可以使用如下的字典理解:

def f1(*args):
        kwargs = {'arg{}'.format(i):j for i,j in enumerate(args,1)}
        f2(**kwargs)

此外,如果您在定义封闭函数之前特别确定您的函数伙伴中没有局部变量,您可以使用 locals :

示例:

>>> globsl_a=8
>>> def fun(arg1,arg2,arg3):
...   print locals()
... 
>>> fun(5,[3,4],'text')
{'arg1': 5, 'arg2': [3, 4], 'arg3': 'text'}
>>> 

以下是我如何根据 as well as Alex Martelli's answer to another question:

解决我的问题
def f2():
    kwargs = inspect.getouterframes(inspect.currentframe(), 2)[1][0].f_locals
    print(kwargs)

def f1(arg1, arg2, arg3)
    f2()  # this should be called right at the first line

>>> f1(1, 2, 3)
{'arg1': 1, 'arg2': 2, 'arg3': 3}