• 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的对象则会报错。

  • 相关阅读:
    java多线程执行时主线程的等待
    数据库锁机制
    数据库事务学习
    EF查询百万级数据的性能测试--多表连接复杂查询
    EF查询百万级数据的性能测试--单表查询
    一文看懂-Docker容器化
    一文看懂-Kafka消息队列
    一文看懂-ElasticSearch全文搜索引擎
    Linux系统(ubuntu)部署Asp.Net Core网站
    Linux系统学习(一)一Linux介绍
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/11872402.html
Copyright © 2020-2023  润新知