是否有可能将正式的参数名称/值作为字典?

时间:2014-03-13 20:43:03

标签: python parameters

如果我将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模块实现这一目标,但它可能过于复杂而不值得。

我怀疑这个问题对这个问题没有好的答案,但我很高兴被证明是错的。实现上述目标的替代方法也是受欢迎的。

4 个答案:

答案 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