• Python类装饰器


    上次介绍了Python的函数装饰器,这次我们来讲一讲Python的类装饰器。

    Python的类装饰器基本语法如下:

    def decorator(cls):
        print "6666666"
        return cls
        
    @decorator
    class Model(object):
        def __init__(self):
            print "model created"
    
    if __name__ == '__main__':
        model = Model()

    decorator即是装饰器函数,输入的cls是一个类,返回也是一个类(其实返回一个可调用对象就可以,例如函数)。所以其实上文的类装饰器就相当于:

    Model = decorator(Model)

    由于装饰器是在加载该模块时运行的,因此上文代码中装饰器输出的"6666666"只会在加载该模块时输出一次。

    这只是最基本的版本,既然返回只要是一个可调用对象就可以,我们就可以对输入的类进行一系列魔改:

    class A(object):
        def __init__(self):
            print "77777"
    
    def decorator(cls):
        return A
    
    @decorator
    class Model(object):
        def __init__(self):
            print "model created"
    
    if __name__ == '__main__':
        model = Model()
        print model

    输出为:

    77777
    <__main__.A object at 0x00B0F850>

    可以看到,通过类装饰器,已经把返回的类悄悄地进行了替换,最终生成的其实是A的对象。

    类装饰器可以对类对象进行修改:

    def decorator(cls):
        cls.test_val = 1
        return cls
        
    @decorator
    class Model(object):
        test_val = 0
        def __init__(self):
            pass
    
    if __name__ == '__main__':
        model = Model()
        print model.test_val

    经过类装饰器的修饰,Model类的test_val值已经被改成了1。

    类装饰器也可以带参数:

    def decorator(num):
        print num
        def dec2(cls):
            return cls
        return dec2
        
    @decorator(1)
    class Model(object):
    def __init__(self): pass

    最后要注意的是,对于继承关系,若f装饰了类A,类B继承了A,则产生B的对象时仍然会调用装饰器f,但装饰器f只会修饰类A。如下代码所示:

    def decorator(num):
        print num
        def dec2(cls):
            print cls
            return cls
        return dec2
    
    def decorator2(cls):
        print cls
        return cls
        
    @decorator(1)
    class Model(object):
        test_val = 0
        def __init__(self):
            pass
    
    @decorator2
    class SubModel(Model):
        def __init__(self):
            pass
    
    if __name__ == '__main__':
        model = SubModel()

    得到的输出为:

    1
    <class '__main__.Model'>
    <class '__main__.SubModel'>

    第一行和第二行是由decorator输出的,第三行是由decorator2输出的。对decorator来说,它只知道Model的存在,因此在decorator中调用SubModel的对象则会报错。

  • 相关阅读:
    _allow_resetlogs_corruption打开数据库
    增量备份恢复DATAGUARD(出现gap并后续有新增数据文件,主从数据文件路径一致)
    dataguard环境破坏后采用rman备份集重新部署
    表空间数据文件迁移到另外的位置(backup as copy tablespace)
    pl/sql无法登录12c问题
    ORA-00845: MEMORY_TARGET not supported on this system
    dataguard主库添加的数据文件路径在从库不存在
    12c expdp
    表进行加密(redact)实验
    创建触发器启动pdb
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/11872402.html
Copyright © 2020-2023  润新知