如果我将Python函数定义为f(a, b, c)
,是否有一种直接的方法来获取将正式名称映射到传入的值的字典?也就是说,从f
内部开始,我希望能够为{'a': 1, 'b': 2, 'c': 3}
电话获取字典f(1, 2, 3)
。
我想这样做,所以我可以直接在字符串替换中使用参数和值,例如"%(a)s %(b)s %(c)s" % d
。我可以做d = dict(a=a, b=b, c=c)
之类的事情,但如果可能的话,我宁愿避免重复。
我知道将f
定义为f(**kwds)
很容易做到,但这也使得函数所期望的参数变得不那么明显。看起来似乎可以通过inspect
模块实现这一目标,但它可能过于复杂而不值得。
我怀疑这个问题对这个问题没有好的答案,但我很高兴被证明是错的。实现上述目标的替代方法也是受欢迎的。
答案 0 :(得分:7)
>>> import inspect
>>> def foo(a,b,c):
... pass
...
>>> inspect.getargspec(foo)
ArgSpec(args=['a', 'b', 'c'], varargs=None, keywords=None, defaults=None)
>>> inspect.getargspec(foo).args
['a', 'b', 'c']
现在,您可以根据这些过滤locals()
。
>>> x = 'outer'
>>> G = 'GLOBAL'
>>> def foo(a, b, c=1, *splat, **splatsplat):
... global G
... d = 'inner'
... b = 'stomped'
... print(locals())
... print(inspect.getargspec(foo))
...
>>> foo(1, 2, 3, 'splat1', 'splat2', named='potato')
{'splatsplat': {'named': 'potato'}, 'splat': ('splat1', 'splat2'), 'd': 'inner', 'b': 'stomped', 'c': 3, 'a': 1}
ArgSpec(args=['a', 'b', 'c'], varargs='splat', keywords='splatsplat', defaults=(1,))
我唯一不知道如何获得的是恢复b
的原始值;我想这可能是不可能的。
答案 1 :(得分:3)
您可以将locals()
用于当前范围:
>>> def f(a, b, c):
... param_values = locals() # Line must be very first in function.
... print(param_values)
>>> f(1, 2, 3)
{'a': 1, 'b': 2, 'c': 3}
方便地,这似乎是您想要的确切输出。在我看来,这是从你指定的函数中的执行此操作的最佳方式。
答案 2 :(得分:1)
您可以使用两个函数来完成它,一个具有良好的接口,另一个具有实现:
def f(a, b, c):
"""Docstring"""
return _f(a, b, c)
def _f(**kwargs):
...
答案 3 :(得分:0)
您可以通过创建一个执行字符串替换的泛型函数来避免更多重复。以下适用于Python 2.7.6和3.3.4:
import inspect
import sys
def print_func_args(call_stack_depth=1):
frame = sys._getframe(call_stack_depth)
funcname = inspect.getframeinfo(frame).function
func = frame.f_globals[funcname]
f_locals = frame.f_locals
args = inspect.getargspec(func).args
print(', '.join(('{}={}'.format(arg, f_locals[arg]) for arg in args)))
def foo(a, b, c):
local_var = 42
print_func_args()
foo(1, 2, 3) # -> a=1, b=2, c=3