zoukankan      html  css  js  c++  java
  • 元类

    元类

    python中一切皆对象,类实际上也是一个个对象,对象就一定是由一个类实例化得到的,那么这个类,就叫做元类。即,产生类的类,叫做元类。

    在python中,type是内置的元类,所有的类都是由type实例化得到的。

    class Student:
        pass
    print(type(Student))
    print(type(dict))
    print(type(object))
    print(type(type))
    
    # <class 'type'>
    # <class 'type'>
    # <class 'type'>
    # <class 'type'>
    

    class关键字底层实现原理

    class 类名:会构造出一个类,实际上是元类实例化产生类这个对象

    类实例化产生对象是:类名()

    比如Student类是由type元类实例化产生,传一堆参数

    type()会调用类的__init__方法

    type(object_or_name, bases, dict)有三个参数

    ​ object_or_name:类的名字,是个字符串

    ​ bases:是它的所有父类

    ​ dict:名称空间,一个字典

    通过type可以直接产生类,不适用class关键字

    所以:class底层就是调用type来实例化产生类(对象)

    补充:exce方法:三个参数

    第一个参数:包含一系列python代码的字符串

    第二个参数:全局作用域(字典形式),如果不指定,默认为globals()

    第三个参数:局部作用域(字典形式),如果不指定,默认为locals()

    可以把exce命令的执行当成是一个函数的执行,会将执行期间产生的名字存放于局部名称空间中

    通过自定义元类控制类的产生

    自定义元类:来控制类的产生,可以控制类名,可以控制类的继承父类,控制类的名称空间

    自定义元类必须继承type,写一个类继承type,那这个类就叫元类

    metaclass=Mymeta,指定一个类生成的时候,用自己写的Mymeta这个元类

    class Mymeta(type):
        pass
    
    class Student(object, metaclass=Mymeta):
        school = 'oldboy'
        def __init__(self, name):
            self.name = name
        def score(self):
            print('100分')
    

    通过自定义元类控制类的调用过程

    调用一个对象,就是触发对象所在类中的__call__方法的执行。

    class Mymeta(type):
        def __call__(self, *args, **kwargs):
            obj = object.__new__(self)
            obj.__init__(*args, **kwargs)
            return obj
    
    class Student(object, metaclass=Mymeta):
        school = 'oldboy'
        def __init__(self, name ,age):
            self.name = name
            self.age = age
    
    s1 = Student('wu', 18)
    print(s1)
    print(s1.__dict__)
    
    # <__main__.Student object at 0x000001AFE0B9EA88>
    # {'name': 'wu', 'age': 18}
    

    在调用s1 = Student('wu', 18)会做三件事:

    1. 调用__call__方法产生一个空对象obj
    2. 调用__init__方法初始化对象obj
    3. 返回初始化好的obj

    有了元类之后的属性查找顺序

    类的属性查找顺序:先从类本身中找-->按mro继承关系去父类中找-->去自己定义的元类中找-->type中找-->报错

    对象的属性查找顺序:先从对象本身中找-->再去类中找-->按mro继承关系去父类中找-->报错

  • 相关阅读:
    营山护照办理
    非北京人员 办理护照
    护照填写注意事项
    美国会议签证——我是正当理由去美国,我能支付(或有人为我支付)我在美国期间的所有费用,办完事我肯定回来, 邀请信,行程表这些材料齐全即可
    urllib2使用2
    python 异常
    python urllib和urllib2 区别
    python类继承
    gcc编译4个阶段
    Vim中如何全选并复制?
  • 原文地址:https://www.cnblogs.com/yunluo/p/11454279.html
Copyright © 2011-2022 走看看