描述
假设我有以下函数,它调用另一个函数:
def f1(arg1, arg2, arg3):
f2(...)
f1
和f2
的自变量相同,或者f2
可能如下所示:
def f2(**kwargs)
pass # whatever
客户端代码将定义并调用f1
,并且要求f1
的签名明确定义所有参数,因此f1
不允许使用**kwargs
。
因此,要从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}
对于您的用例
问题是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}
这里需要的是将父函数的参数传递给一个封闭函数。首先,我必须说,你不能使用local()
,因为local
包含局部变量,局部变量包含参数和你在函数好友中定义的所有局部变量,但如果你只想在所有参数都是动态的时获得它们,就像你的例子一样,我建议在parents函数中使用*args
:
def f1(*args):
但这里有一点,因为您想要使用**kwargs
,并且它是为了收集任意关键字的参数,您需要将其初始化为参数的名称。
例如,您可以使用以下dict理解:
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'}
>>>
以下是我如何根据Anand S Kumar的回答以及Alex Martelli对另一个问题的回答来解决我的问题:
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}