2017-02-21 59 views
0

我正在写一个装饰器,它会在函数调用中为不正确的参数数量捕获TypeError,并将打印自定义消息。该代码是在这里:在装饰器中保存签名python 2

import inspect 

def inspect_signature(f): 
    def decorate(*args, **kwargs): 
     try: 
      f(*args, **kwargs) 
     except TypeError as e: 
      print('Failed to call "{}" with signature {}. Provided args={} and kwargs={}.'.format(
       f.__name__, inspect.getargspec(f).args, args, kwargs)) 
     return f 
    return decorate 


@inspect_signature 
def func(foo, bar): 
    pass 
func('a') 
func('a', 'b') 

我得到以下输出:

Failed to call "func" with signature ['foo', 'bar']. Provided args=('a',) and kwargs={}. 
Called successfully with foo=a, bar=b 
ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None) 

函数签名是空的。请给我一个解决方案,我该如何保留它?

PS:我使用的是python2,无法切换到python3。

+0

我已更新答案。你有这个吗? –

回答

0

你错过了这里。 func(* foo,** bar)

在你的情况下func('a')不能正常工作,因为你给了它的固定参数。

你需要可变数量的参数传递给你的函数

@inspect_signature 
def func(*foo, **bar): 
    pass 
+0

我没有将可变数量的参数传递给该函数。我已经确定了两个论点。我知道'func('a')'不会工作,所以我写了一个装饰器,它将打印一个定制的消息而不是python内置的错误消息,但是我的原始函数签名会丢失。所以我想保留它。 –

+0

@python_user那么原始签名函数的定义是什么? –

0

你可以参考Preserving signatures of decorated functions

总之,您可以在Python2和Python3中使用decorator模块。当您使用Python3.4 +时,可以使用inspect.wraps来保留装饰函数的签名。

如果您不想使用decorator模块,则可以使用eval来制作装饰器。一般来说,eval是不受欢迎的,因此,decorator模块可能是Python2中的最佳解决方案。