类装饰器装饰类方法
不带参数
from functools import wraps import types class CatchException: def __init__(self,origin_func): wraps(origin_func)(self) def __get__(self, instance, cls): if instance is None: return self else: return types.MethodType(self, instance) #在这里,__get__() 的目的是创建一个绑定方法对象 (最终会给这个方法传递self参数)。 def __call__(self,*args, **kwargs): try: print('haha') print(self.__wrapped__) return self.__wrapped__(*args, **kwargs) except Exception as e: print(e) return 'an Exception raised.' class Test(object): def __init__(self): pass def revive(self): print('revive from exception.') # do something to restore @CatchException def read_value(self): print('here I will do something') # do something. # #相当于read_value = CatchException(read_value) if __name__ == '__main__': t = Test() print(Test.read_value)#结果 <__main__.CatchException object at 0x00000188516A9608> print(t.read_value)#结果 <bound method Test.read_value of <__main__.Test object at 0x00000188516A9648>> print(Test.read_value.__get__(t,Test)) #结果 <bound method Test.read_value of <__main__.Test object at 0x00000188516A9648>> t.read_value() #t.read_value 相当于 Test.read_value.__get__(t,Test),返回值为types.MethodType(CatchException(read_value), t) #types.MethodType(CatchException(read_value), t) 相当于执行了将CatchException(read_value)实例绑定到t上 #则t.read_value()相当于types.MethodType(CatchException(read_value), t)()
带参数
class CatchException: def __init__(self,level): self.level = level def __call__(self,origin_func): def wrapper(origin_func_self,*args, **kwargs): print(self.level) try: u = origin_func(origin_func_self,*args, **kwargs) return u except Exception as e: origin_func_self.revive() #不用顾虑,直接调用原来的类的方法 print(e) return 'an Exception raised.' return wrapper class Test(object): def __init__(self): pass def revive(self): print('revive from exception.') # do something to restore @CatchException(level='error') def read_value(self): print('here I will do something.') # do something. # if __name__ == '__main__': t = Test() t.read_value()