Yes, you can write a class decorator; the following will allow you to decorate each of the functions in the class:
def decorate_all_functions(function_decorator):
def decorator(cls):
for name, obj in vars(cls).items():
if callable(obj):
try:
obj = obj.__func__ # unwrap Python 2 unbound method
except AttributeError:
pass # not needed in Python 3
setattr(cls, name, function_decorator(obj))
return cls
return decorator
The above class decorator applies a given function decorator to all callables on a class.
Say you have a decorator that prints the name of the function being called before and after:
from functools import wraps
def print_on_call(func):
@wraps(func)
def wrapper(*args, **kw):
print('{} called'.format(func.__name__))
try:
res = func(*args, **kw)
finally:
print('{} finished'.format(func.__name__))
return res
return wrapper
then the class decorator could be applied with:
@decorate_all_functions(print_on_call)
class Foo:
def func1(self):
print('1')
def func2(self):
print('2')
Demo:
>>> @decorate_all_functions(print_on_call)
... class Foo:
... def func1(self):
... print('1')
... def func2(self):
... print('2')
...
>>> c = Foo()
>>> c.func1()
func1 called
1
func1 finished
>>> c.func2()
func2 called
2
func2 finished
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…