前后端知识库 前后端知识库
首页
    • JavaScript
    • React
    • Vue
  • Python
  • Sanic
  • Linux
  • Ansible
归档
GitHub (opens new window)
首页
    • JavaScript
    • React
    • Vue
  • Python
  • Sanic
  • Linux
  • Ansible
归档
GitHub (opens new window)
  • Sanic

  • Python

    • Python 的动态类型介绍
    • 数字类型
    • Set类型
    • 字符串
    • 列表
    • 元组
    • 通用序列
    • 字典
    • 文件
    • 语句和语法
    • 赋值语句
    • 打印
    • if语句
    • loop循环
    • 迭代器和生成器
    • 文档
    • 函数
    • 作用域
    • 参数
    • 函数的高级特性
    • 模块
    • 模块包
    • 模块高级用法
    • 类 class
    • Python命名空间
    • 运算符重载
    • 类的设计模式
    • 类的高级主题
    • 异常
    • 异常对象
    • Unicode与字节串
    • 管理属性
    • 装饰器
    • 元类
    • 执行细节
  • backend
  • Python
devin
2023-09-09

元类

# 元类

1.元类是一种特殊的类,它用于创建类。元类机制允许我们在一条class语句的末尾自动插入某些逻辑。它在类对象创建时运行,是管理和扩展类的钩子。元类不是管理类的实例,而是管理类本身

2.尽管类的装饰器通常用来管理或者扩展类实例,但是他们也可以用于管理和扩展类对象本身,也与元类的功能重叠

3.Python3 中,所有用户定义的类都是type类对象的实例,type类是应用最广的元类

4.class语句的内部机制:在一条class语句的末尾,Python 会调用type类的构造函数来创建一个class对象。

MyClass=type(classname,superclasses,attributedict) #新建了一个类,类名叫MyClass
# classname:类名,会成为MyClass类的 .__name__属性
# superclasses:类的超类元组,会成为MyClass类的 .__bases__属性
# attributedict:类的命名空间字典,会成为MyClass类的 .__dict__ 属性
# 这个语句也是动态创建类对象的方法
1
2
3
4
5
  • type类定义了一个.__call__(...)方法。该方法运行type类定义的两个其他方法: _ .__new__(mclass,classname,superclasses,attributedict)方法,它返回新建的MyClass类 > mclass:为本元类,这里是type类

    classname:为被创建的类的类名,这里是'MyClass'
    superclasses:为被创建的类的超类元组
    attributedict:为被创建的类的名字空间字典
    _ .__init__(customclass,classname,superclasses,attributedict)方法, 它初始化新建的MyClass类 > customclass:为被创建的类,这里是MyClass类
    classname:为被创建的类的类名,这里是'MyClass'
    superclasses:为被创建的类的超类元组
    attributedict:为被创建的类的名字空间字典

    5.所有的类型均由type类创建。要通知 Python 用一个定制的元类来创建类,可以直接声明一个元类来拦截常规的类创建过程。

定义元类:(所有元类必须是type的子类)

class MetaClass(type):
	def __new__(mclass,classname,superclasses,attributedict):
		return type.__new__(mclass,classname,superclasses,attributedict)
	def __init__(customclass,classname,superclasses,attributedict):
		return type.__init__(customclass,classname,superclasses,attributedict)
1
2
3
4
5

使用元类:

class MyClass(metaclass=MetaClass):
	pass
1
2
  • 继承的超类也列在括号中,但是要在元类之前,也用逗号分隔: class MyClass(BaseCls1,BaseCls2,metaclass=MetaClass)

  • 使用元类声明后,在class语句底部进行创建MyClass类时,改为调用元类MetaClass而不是默认的type: MyClass=Meta('MyClass,superclasses,attributedict)`

  • 元类MetaClass要实现元类协议: _ 重载元类的.__new__(Meta,classname,superclasses,attributedict)方法,它返回新建的MyClass类 _ 重载元类的.__init__(customclass,classname,superclasses,attributedict)方法, 它初始化新建的MyClass类 >type类的.__call__(...)方法将创建和初始化MyClass类对象的调用委托给元类 MetaClass`

    元类

    6.元类有的时候不一定是个真正的类,它也可能是一个函数。任何可调用对象都可以作为一个元类,只需要按照以下的做法:

def MetaFactory(classname,superclasses,attributedict):
	...
	return type(classname,superclasses,attributedict) #动态创建类型
class A(metaclass=MetaFactory):
	pass
1
2
3
4
5
  • 在class语句的末尾会调用MetaFactory函数

    函数做元类

    7.事实上元类只用于创建类对象,元类并不产生元类自己的实例。因此元类的名字查找规则有些不同:.__call__,.__new__,.__init__方法均在类中查找

    8.元类的继承:

  • 元类声明由子类继承,即子类的构建也是由父类的元类负责

    元类的继承

  • 如果元类是以函数的方式声明,则子类的构建不再继承这个函数式元类

    元类的继承

  • 元类中的属性并不进入自定义类的命名空间,即元类中声明的一些类属性与被创建类的名字空间无关(他们是两个不同的类)

    元类和被创建类的属性

  • 自定义的类,如果没有显示指定元类,也没有指定父类,则默认使用type作为元类(即常规的类创建机制)

编辑 (opens new window)
上次更新: 2023/09/09, 12:09:00
装饰器
执行细节

← 装饰器 执行细节→

Theme by Vdoing | Copyright © 2023-2023 devin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式