pro*_*eek 4 python doctest decorator python-decorators
我试图使用Python装饰器来捕获异常并记录异常.
import os.path
import shutil
class log(object):
def __init__(self, f):
print "Inside __init__()"
self.f = f
def __call__(self, *args):
print "Inside __call__()"
try:
self.f(*args)
except Exception:
print "Sorry"
@log
def testit(a, b, c):
print a,b,c
raise RuntimeError()
if __name__ == "__main__":
testit(1,2,3)
Run Code Online (Sandbox Code Playgroud)
它工作正常
Desktop> python deco.py
Inside __init__()
Inside __call__()
1 2 3
Sorry
Run Code Online (Sandbox Code Playgroud)
问题是,当我尝试使用doctest进行测试时
@log
def testit(a, b, c):
"""
>>> testit(1,2,3)
"""
print a,b,c
raise RuntimeError()
if __name__ == "__main__":
import doctest
doctest.testmod()
Run Code Online (Sandbox Code Playgroud)
似乎没有任何事情发生.
Desktop> python deco2.py
Inside __init__()
Run Code Online (Sandbox Code Playgroud)
这有什么问题?
修饰函数(实际上是一个类实例)不会获得__doc__原始函数的属性(这就是doctest解析).你可以复制__doc__到类实例,但是......老实说,我真的没有看到这里需要一个类 - 你可能更好只是使用functools.wraps
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args):
try:
return func(*args)
except Exception:
print "sorry"
return wrapper
Run Code Online (Sandbox Code Playgroud)
您需要将文档字符串复制到装饰器中:
class log(object):
def __init__(self, f):
print "Inside __init__()"
self.f = f
self.__doc__ = f.__doc__
def __call__(self, *args):
print "Inside __call__()"
try:
self.f(*args)
except Exception:
print "Sorry"
Run Code Online (Sandbox Code Playgroud)
装饰器替换了装饰函数,并且只有通过复制文档字符串,该属性才对任何人可见。
您可以利用functools.update_wrapper()此处为您复制文档字符串以及其他几个属性:
from functools import update_wrapper
class log(object):
def __init__(self, f):
print "Inside __init__()"
self.f = f
update_wrapper(self, f)
def __call__(self, *args):
print "Inside __call__()"
try:
self.f(*args)
except Exception:
print "Sorry"
Run Code Online (Sandbox Code Playgroud)