zoukankan      html  css  js  c++  java
  • 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的对象则会报错。

  • 相关阅读:
    掌握 bind, apply 和 call 的用法
    导航页
    SSIS连接Oracle数据源
    redhat6.4 配置centos6 yum替换
    java web程序 上机考试做一个登陆注册程序
    java web程序 jdbc连接数据库错误排查方法
    java web程序 上机考试登陆界面设计实现
    java web 程序---缓冲代码
    java web程序 String的valueOf方法总集
    java web程序 登陆验证页面 4个页面人性化设置
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/11872402.html
Copyright © 2011-2022 走看看