• 浅谈元类(个人理解)


    元类

    什么叫元类

    我们知道在python中一切皆对象(object),那么所以有的对象都成了object的子类,那么object类又是由谁创建的呢?

    实际上,能够创建类的类,叫元类。还有一个概念就是:元类创建了object类,同时又是object类的子类(这是什么鬼?我们就不去考虑这个逻辑了,已经完美解决了先有鸡还是先有蛋的问题了)。

    元类实际还是所有类的创建者,即使所有类(包括元类自己)都是object的子类,他们的关系如下:

    Interesting......

    class的底层

    当我们使用class 类名的时候,就会把类构造出来。实际上是元类实例化产生类,隐藏的语法如下:

    type(name, bases, dict),传入三个参数时,代表class语句的动态形式,name字符串即类名并且会成为__name__属性;bases元组列出基类并且会成为__bases__属性;而dict字典代表类的名称空间即__dict__属性。

    例如,以下两条语句会创建相同的type对象:

    class A:
        a = 1
        
    A = type('A',(object,), dict(a = 1))
    

    使用type控制类的产生

    自定义元类:继承type:

    class Mymeta(type):
        def __init__(self, name, bases, dic):
            '''控制类的产生,在__new__之后'''
            #self 是A这个类(type的对象)
            #在这个位置,其实self也就说A这个类,内部已经有东西了,名称空间已经有东西了
            #所以在这个地方,可以通过dic来判断名称空间
            #也可以直接通过self.__dict__/self.属性 来判断
            a = self.__dict__.get('attr').get('name')  # 后面做了修改
            if not a:
                raise Exception("没有name 属性")
            super().__init()
            
        def __new__(cls, name, bases, dic):
            '''最根本上控制类产生,其实本质最根上也不是它,是type的__call__,但是我们控制不了了'''
            dic2 = {'attr' : {}}
            for k,v in dic.items():
                if not k.startswith('__'):
                    dic2['attr'][k] = v
                else:
                    dic2[k] = v
            return type.__new__(cls, name, bases, dic2)  # 必须返回
    
        def __call__(self, *args, **kwargs):
            '''控制类对象的产生'''
            print(args,kwargs)
            obj = self.__new__(self)
            obj.__init__(*args, **kwargs)
            return obj   # 必须返回一个类的对象
    
    
    class A(metaclass=Mymeta):
        name = 'ddd'
    
        def __init__(self, id):
            self.id = id
    
        def __repr__(self):
            return 123
    
    a = A(111)
    

    元类里最重要的有三个魔术方法:

    • __init__:控制类的产生,在__new__之后
    • __call__:控制类对象的产生
    • __new__:最根本上控制类产生,其实本质最根上也不是它,是type的__call__,但是我们控制不了了

    更详细的内容会在将来的某一天更新...

  • 相关阅读:
    ansible plugins 列表
    ansible common modules
    CentOS 7.3降低内核版本为7.2
    ansible ad-hoc 参考
    kafka监控工具kafka-manager
    zookeeper监控之taokeeper
    linux的ulimit各种限制之深入分析
    docker版的zabbix部署
    kubernetes介绍(1)
    部署k8s时容器中ping不通
  • 原文地址:https://www.cnblogs.com/Du704/p/11529024.html
Copyright © 2020-2023  润新知