• 元类和__metaclass__


    # python 里面一切都是对象!!函数是对象、变量是对象、类也是对象
    # 实例对象是由类创建的,1是由int类创建的,"haha"是由str类创建的,类是由元类创建的!!!
    # 元类是创建类的类(类是type类的实例)(当解释器遇到class关键字的时候,就创建出了这个类对象)
    
    # 一下展示一下这些对象是由什么类创建的
    print("haha".__class__)
    print(type("haha"))
    
    list = [1, 2, 3, 4]
    print(type(list))
    print(list.__class__)
    
    
    class test01(object):
        pass
    
    
    obj = test01()
    print(type(obj))
    print(type(test01))
    print("*" * 60)
    
    
    # 动态地创建类
    # 使用type()内建函数动态地创建类(内建函数type()有两种功能!在设计上是非常蠢的,但是为了保持python的版本向上兼容性)
    # type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
    # 使用type创建带有属性和方法的类
    def show(self):
        print("this count is %d" % (self.count))
    
    
    # 带有静态方法
    @staticmethod
    def run():
        print("我只想奔跑,没有self")
    
    
    # 带有类方法
    @classmethod
    def addCount(cls):
        cls.count += 1
    
    
    # 这一句是创建了一个类(name和age是这个类的类属性)
    test02 = type("test02", (), {"count": 1, "show": show, "run": run, "addCount": addCount})
    # 这一句是创建类test02的实例对象
    t1 = test02()
    print(t1.count)
    t1.show()
    t1.run()
    t2 = test02()
    t2.addCount()
    t2.show()
    print("*" * 60)
    
    
    # 自定义元类
    # __metaclass__属性
    # class Foo(object):
    #     __metaclass__ = something…
    #     ...省略...
    # 一个类是怎么被创建的????python解释器看到class关键字的时候,并没有在内存中这个类,而是在寻找__metaclass__这个属性,
    # 在本类中找不到就到父类中找,如果都找不到,就使用内置的type()来创建这个类
    # 我们通过重写__metaclass__这个属性,实现自定义元类的目的
    
    
    # 自定义设置:实例对象的所有的属性都是大写
    class UpperAttrMetaClass(type):
        # __new__ 是在__init__之前被调用的特殊方法
        # __new__是用来创建对象并返回之的方法
        # 而__init__只是用来将传入的参数初始化给对象
        # 你很少用到__new__,除非你希望能够控制对象的创建
        # 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__
        # 如果你希望的话,你也可以在__init__中做些事情
        # 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用
        def __new__(cls, future_class_name, future_class_parents, future_class_attr):
            # 遍历属性字典,把不是__开头的属性名字变为大写
            newAttr = {}
            for name, value in future_class_attr.items():
                if not name.startswith("__"):
                    newAttr[name.upper()] = value
    
            # 方法1:通过'type'来做类对象的创建
            # return type(future_class_name, future_class_parents, newAttr)
    
            # 方法2:复用type.__new__方法
            # 这就是基本的OOP编程,没什么魔法
            # return type.__new__(cls, future_class_name, future_class_parents, newAttr)
    
            # 方法3:使用super方法
            return super(UpperAttrMetaClass, cls).__new__(cls, future_class_name, future_class_parents, newAttr)
    
    
    # python3的用法
    class Foo(object, metaclass=UpperAttrMetaClass):
        bar = 'bip'
    
    
    print(hasattr(Foo, 'bar'))
    # 输出: False
    print(hasattr(Foo, 'BAR'))
    # 输出:True
    
    f = Foo()
    print(f.BAR)
    # 输出:'bip'
    
    # 元类其实用的特别特别少!!
    # 拦截类的创建
    # 修改类
    # 返回修改之后的类
  • 相关阅读:
    [Spring开发]获取上下文对象
    [Dubbo开发]Dubbo日志插件实现(打包)
    [Dubbo开发]Dubbo日志插件实现(未打包)
    [Java开发]打印当前路径到控制台
    [Dubbo开发]Dubbo拦截器(Filter)初探
    [Dubbo开发]配置简单的生产者和消费者
    [Dubbo开发]Zookeeper配置
    [Dubbo开发]Maven安装与配置
    EL表达式的特性
    oracle中rownum的使用
  • 原文地址:https://www.cnblogs.com/tangxlblog/p/9949262.html
Copyright © 2020-2023  润新知