zoukankan      html  css  js  c++  java
  • python 装饰器(七):装饰器实例(四)类装饰器装饰类以及类方法

    类装饰器装饰类方法

    不带参数

    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()
  • 相关阅读:
    卡牌配对
    SNOI2017 礼物
    【BZOJ2893】征服王
    景中人
    钦点
    杨柳
    兼容IE与firefox、chrome的css 线性渐变(linear-gradient)
    使用C# DES解密java DES加密的字符串
    jQuery插件autoComplete使用
    hadoop SQL使用
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12950274.html
Copyright © 2011-2022 走看看