I was trying to use Python decorator to catch exceptions and log the exceptions.
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)
It works fine
Desktop> python deco.py
Inside __init__()
Inside __call__()
1 2 3
Sorry
The issue is that when I tried to use for testing with doctest
@log
def testit(a, b, c):
"""
>>> testit(1,2,3)
"""
print a,b,c
raise RuntimeError()
if __name__ == "__main__":
import doctest
doctest.testmod()
nothing seems to be happening.
Desktop> python deco2.py
Inside __init__()
What's wrong with this?
The decorated function (which is actually a class instance) doesn't get the __doc__
attribute of the original function (which is what doctest
parses). You could just copy __doc__
over to the class instance, but ... Honestly, I don't really see the need for a class at all here -- you'd probably be better just using functools.wraps
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args):
try:
return func(*args)
except Exception:
print "sorry"
return wrapper
You need to copy the docstring over to your decorator:
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"
The decorator replaces the decorated function, and only by copying over the docstring would that attribute be visible to anyone.
You could make use of functools.update_wrapper()
here to do the copying of the docstring, as well as several other attributes, for you:
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With