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()
  • 相关阅读:
    如何解决由于启动用户实例的进程时出错,导致无法生成 SQL Server 的用户实例。该连接将关闭。
    客户端中检测到有潜在危险的Request.Form 值的处理办法 VS2010 .NET 4.0
    VS2010中解决数据集和ObjectDataSource无法自动生成UPDATA和DELETE方法
    使用Eclipse的几个必须掌握的快捷方式
    使用OjectDataSource数据源绑定ListView 高效分页
    NVIDIA SDK 10
    [转]我要的不多
    本月推荐电影
    加/解密
    GDC 2007 Presentations of NV now available.
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12950274.html
Copyright © 2011-2022 走看看