Python 元类 metaclass 详解

简介: Python 元类 metaclass 详解

元类(metaclass)是 Python 中一个高级且相对较少使用的概念。元类可以被视为类的类,它控制类的创建过程。


一、基本概念


在 Python 中,一切皆对象。为了避免混淆,我们约定两个术语:


  • 类实例:当我们定义一个类时,实际上是在创建一个对象,这个对象就是类本身,我们将类本身这个对象称为 类实例
  • 类的实例:我们将使用类创建的实例称之为 类的实例


生活中的例子:


  • 我们可以将 元类 理解为 制作蛋糕模具的机床,将 理解为 制作蛋糕的模具
  • 制作蛋糕模具是元类创建的 类实例蛋糕 是蛋糕模具创建的 蛋糕类的实例


二、基本原理


元类 控制 类实例 的创建过程,其中 __new__ 方法用于创建 类实例,而 __init__ 方法用于初始化这个 类实例


控制 类的实例 的创建过程,其中 __new__ 方法用于创建 类的实例,而__init__方法用于初始化这个 类的实例


三、核心作用


元类的核心作用是控制类的创建过程,允许我们在类被实际创建之前修改它,这使得我们可以在类级别上进行高级的定制,例如添加额外的属性、修改类的行为等。


四、Demo 示例


示例 1:简单的元类

class SimpleMeta(type):
    registered_classes = []
    def __new__(cls, name, bases, dct):
        """创建类实例"""
        print("Generate new instance")
        return super().__new__(cls, name, bases, dct)
    def __init__(cls, name, bases, dct):
        """初始化类实例"""
        print("Init new instance")
        super().__init__(name, bases, dct)
        SimpleMeta.registered_classes.append(cls)
class MyClass1(metaclass=SimpleMeta):
    pass
print('========================================')
class MyClass2(metaclass=SimpleMeta):
    pass
print('========================================')
print(f"Registered classes: {SimpleMeta.registered_classes}")


输出结果:

Generate new instance
Init new instance
========================================
Generate new instance
Init new instance
========================================
Registered classes: [<class '__main__.SimpleMeta'>, <class '__main__.SimpleMeta'>]


示例说明:

元类 SimpleMeta 中的 __init__ 方法在 __new__ 方法执行后被调用,用于收集已注册的类的信息,展示了元类的实际用途。


示例 2:蛋糕模具定制

class ShapeMeta(type):
    def __new__(cls, name, bases, dct):
        # 获取类的名称并根据不同的类名进行定制
        if name == 'RoundCake':
            # 定制化操作
            dct['shape'] = 'Round'
        if name == 'TriangleCake':
            # 定制化操作
            dct['shape'] = 'Triangle'
        return super().__new__(cls, name, bases, dct)
class RoundCake(metaclass=ShapeMeta):
    pass
class TriangleCake(metaclass=ShapeMeta):
    pass
my_round_cake = RoundCake()
my_triangle_cake = TriangleCake()
print(my_round_cake.shape)  # 输出 Round
print(my_triangle_cake.shape)  # 输出 Triangle


输出结果:

Round
Triangle


示例说明:

元类 ShapeMeta 根据类的名称控制类的形状属性,这里可以看出元类对类创建过程的控制。


综合示例:面向切面编程

import functools
def listening(func):
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        print(f'do something before calling function {func.__name__}')
        result = func(self, *args, **kwargs)
        print(f'do something after calling function {func.__name__}')
    return wrapper
class ListeningMeta(type):
    def __new__(cls, name, bases, dct):
        for key, value in dct.items():
            if callable(value) and not key.startswith("__"):
                dct[key] = listening(value)
        return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=ListeningMeta):
    def __init__(self, data):
        self._data = data
    @property
    def data(self):
        print(self._data)
        return self._data
    def do_somthing(self):
        print(f'do_somthing with {self._data}')
a = MyClass(1)
a.data
a.do_somthing()


输出结果:

1
do something before calling function do_somthing
do_somthing with 1
do something after calling function do_somthing


示例说明:

元类 ListeningMeta 展示了元类如何用于在不修改原始类代码的情况下添加额外的行为,实现面向切面编程的效果。


五、要点小结


  • 元类是类的类,用于控制类实例的创建过程和初始化过程。
  • __new__ 用于创建类实例,__init__ 用于初始化实例。
  • 元类的主要作用是允许在类被创建之前修改它,如添加属性、修改行为。
  • 元类适用于对类创建过程进行深度干预的特殊需求,对于大多数情况,普通类定义和继承已经足够,元类提供额外的灵活性。
目录
相关文章
|
5月前
|
API Python
82 python高级 - 元类(下)
82 python高级 - 元类(下)
27 0
|
1月前
|
编译器 API 数据库
Python教程第7章 | 元类
学习如何自定义元类。通过自定义元类,我们可以实现对类的行为的修改和扩展,从而实现更高级的编程技巧。
16 0
|
2月前
|
程序员 C++ Ruby
Python 的元类设计起源自哪里?
Python 的元类设计起源自哪里?
14 0
|
2月前
|
Python
解释Python中的元类(Metaclass)是什么,如何使用元类?
解释Python中的元类(Metaclass)是什么,如何使用元类?
13 0
|
3月前
|
数据库 Python
|
3月前
|
Python
Python 元类 metaclass 详解
- 元类是类的类,用于控制类实例的创建过程和初始化过程。 - `__new__` 用于创建类实例,`__init__` 用于初始化实例。 - 元类的主要作用是允许在类被创建之前修改它,如添加属性、修改行为。 - 元类适用于对类创建过程进行深度干预的特殊需求,对于大多数情况,普通类定义和继承已经足够,元类提供额外的灵活性。
26 0
|
4月前
|
Python
Python 高级主题:什么是元类(Metaclass)?在 Python 中如何使用元类?
Python 高级主题:什么是元类(Metaclass)?在 Python 中如何使用元类?
|
4天前
|
机器学习/深度学习 数据挖掘 API
pymc,一个灵活的的 Python 概率编程库!
pymc,一个灵活的的 Python 概率编程库!
10 1
|
4天前
|
人工智能 算法 调度
uvloop,一个强大的 Python 异步IO编程库!
uvloop,一个强大的 Python 异步IO编程库!
17 2