元类

元类

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继承关系去父类中找-->报错

原文地址:https://www.cnblogs.com/yunluo/p/11454279.html