如何避免装饰器破坏参数检查?

时间:2015-09-01 23:58:53

标签: python python-3.x

我已经创建了这个装饰器,可以帮助我捕获并记录异常:

def log_exceptions(f):
    '''Catch exception in method, format message and log it.'''
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except CommandError:
            raise
        except Exception as e:
            error_type = sys.exc_info()[0].__name__
            error_desc = str(e)
            error_file = os.path.basename(sys.exc_info()[2].tb_next.tb_frame.f_code.co_filename)
            error_line = sys.exc_info()[2].tb_next.tb_lineno
            logger.info('Exception at %s (line: %s), %s: %s',
                        error_file, error_line, error_type, error_desc)
            return
    return wrapper

现在,如果我定义方法foo:

class A(object):
    def foo(self, arg1, arg2 = None):
        pass

检查它,我得到了它的参数列表:

>>> a = A()
>>> import inspect
>>> inspect.getfullargspec(a.foo)
FullArgSpec(args=['self', 'arg1', 'arg2'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})

但是如果我使用log_exceptions装饰器:

class A(object):
    @log_exceptions
    def foo(self, arg1, arg2 = None):
        pass

对参数的检查不再起作用(它得到装饰者的论点):

>>> a = A()
>>> import inspect
>>> inspect.getfullargspec(a.foo)
FullArgSpec(args=[], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={})

有谁知道避免这种情况的方法吗?

1 个答案:

答案 0 :(得分:1)

我在PEP-0362找到了解决方案:https://www.python.org/dev/peps/pep-0362

用包装的签名替换包装器的签名:

<pre><asp:Label runat="server" /></pre>