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

时间:2015-07-19 15:24:53

标签: python reflection arguments inspect

描述

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

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

f1f2的论点相同,或f2可能如下:

def f2(**kwargs)
    pass  # whatever

客户端代码将定义并调用f1,并且要求f1的签名明确定义所有参数,因此{{1}不允许**kwargs }}

所以,要从f1内拨打f2,我必须这样做:

f1

问题

有没有办法可以在没有明确写入的情况下将参数传递给def f1(arg1, arg2, arg3): f2(arg1, arg2, arg3) ?理想情况下,我认为它应该是这样的:

f2

任何魔法?

更新

可能的解决方案

我有没有办法将def f1(arg1, arg2, arg3): kwargs = <Some Magic Here> f2(**kwargs) locals()结合起来汇总我的inspect.getargspec()

3 个答案:

答案 0 :(得分:2)

一般

好吧,您可以创建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}

对于您的用例

  

问题是f1将由客户端定义,参数处理对所有人来说都很常见,所以我想隐藏处理细节,以便客户端将所有参数传递给实现。此外,我想简化定义并自动传递所有参数,而不是明确指定它们。

函数内的

locals()会返回当时函数中局部变量的副本作为字典。如果在您的问题中如果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}

答案 1 :(得分:1)

你想要的是将父函数的参数传递给一个封闭的函数。所以我必须说你不能使用local(),因为local包含的局部变量包含你在函数伙伴中定义的参数和所有局部变量,但是如果你只是想在动态时得到所有的参数并且像你的例子一样,我建议在父函数中使用*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'}
>>> 

答案 2 :(得分:1)

以下是我根据Anand S Kumar's answer以及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}