類裝飾器裝飾類方法
不帶參數
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()