2017-08-05 76 views
1

为了记录目的,我尝试自动捕获传递给函数内部函数的参数并将它们转换为arg : value的字典。 我试过inspect.signature()模块,但它仅与函数的默认输入,而不是参数传递给它如何在字典中捕捉函数的输入参数

import inspect 

def my_add_func(a, b ,c=3): 
    sig = inspect.signature(my_add_func) 
    print("my_add_func args : {0}".format(sig)) 
    return a + b + c 

if __name__ == '__main__': 
    my_add_func(10, 2, 3) 

输出提供:

(a, b, c=3) 

而我想有:

{a: 10, b: 2, c:3} 

我该怎么做?

回答

1

你可以使用signature.bind

import inspect 

def my_add_func(a, b ,c=3): 
    sig = inspect.signature(my_add_func) 
    print("my_add_func args : {0}".format(sig.bind(a, b, c))) # changed here 
    return a + b + c 

if __name__ == '__main__': 
    my_add_func(10, 2, 3) 

这给:

my_add_func args : <BoundArguments (a=10, b=2, c=3)> 

如果你想把它当作一个映射(字典类),您可以访问BoundArguments.arguments属性:

>>> sig.bind(a, b, c).arguments 
OrderedDict([('a', 10), ('b', 2), ('c', 3)]) 

甚至将其转换为纯字典:

>>> dict(sig.bind(a, b, c).arguments)) 
{'a': 10, 'b': 2, 'c': 3} 
+0

按预期工作谢谢,我只是按照@Yuval Ben Ari的建议添加'apply_default()'。另外我发现''locals()'更容易使用。它适合我的情况,因为我只想在函数的开头就抓住参数。 – MCMZL

+0

@MCMZL如果你这样做,直接在函数中检查你不需要'apply_default()',只有当你试图从外部检查一个函数时才有意思。 – MSeifert

+0

@MCMZL我很高兴它的工作,请不要忘记[接受](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)最有帮助的答案:) – MSeifert

0

,如果你想记录功能的输入您应使用包装:

import inspect 

def log_args(func): 
    def log_and_call(*args, **kwargs): 
     sig = inspect.signature(func) 
     bound_args = sig.bind(*args, **kwargs) 
     bound_args.apply_defaults() 
     loggable_args = bound_args.arguments 

     print("Function name: " + func.__name__) 
     for key, val in loggable_args.items(): 
      print(key + " = " + str(val)) 

     return func(*args, **kwargs) 
    return log_and_call 

@log_args 
def do_sum(a, b, c=0): 
    return a + b + c 


x = do_sum(1,b=2) 

这种方式很容易记录每一个函数调用,并阻止样板代码。
请注意,我使用apply_defaults,因此如果未提供不同的值,它将打印默认参数的值。
在这个例子中,我也给出了b的名字,虽然它不是一个默认值的参数,只是为了显示它的作品。
您可以用写入到记录器或类似的东西来替换打印件。

+1

@MSeifert是的,我用'apply_defaults'。我解释了为什么在编辑 –

+0

时@MSeifert我也没有转换为'dict',所以参数的顺序不会丢失。 –

+0

谢谢'apply_default()'确实非常有用。我还发现'locals()'描述[这里](https://stackoverflow.com/questions/7969949/whats-the-difference-between-globals-locals-and-vars),可以用于我的情况 – MCMZL