Python 元类 metaclass 详解

2024-01-15 18:28
文章标签 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):passprint('========================================')class MyClass2(metaclass=SimpleMeta):passprint('========================================')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):passclass TriangleCake(metaclass=ShapeMeta):passmy_round_cake = RoundCake()
my_triangle_cake = TriangleCake()print(my_round_cake.shape)  # 输出 Round
print(my_triangle_cake.shape)  # 输出 Triangle

输出结果:

Round
Triangle

示例说明:

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

综合示例:面向切面编程

import functoolsdef 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 wrapperclass 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@propertydef data(self):print(self._data)return self._datadef 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__ 用于初始化实例。
  • 元类的主要作用是允许在类被创建之前修改它,如添加属性、修改行为。
  • 元类适用于对类创建过程进行深度干预的特殊需求,对于大多数情况,普通类定义和继承已经足够,元类提供额外的灵活性。

这篇关于Python 元类 metaclass 详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/609801

相关文章

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

Python实现快速扫描目标主机的开放端口和服务

《Python实现快速扫描目标主机的开放端口和服务》这篇文章主要为大家详细介绍了如何使用Python编写一个功能强大的端口扫描器脚本,实现快速扫描目标主机的开放端口和服务,感兴趣的小伙伴可以了解下... 目录功能介绍场景应用1. 网络安全审计2. 系统管理维护3. 网络故障排查4. 合规性检查报错处理1.

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

Python轻松实现Word到Markdown的转换

《Python轻松实现Word到Markdown的转换》在文档管理、内容发布等场景中,将Word转换为Markdown格式是常见需求,本文将介绍如何使用FreeSpire.DocforPython实现... 目录一、工具简介二、核心转换实现1. 基础单文件转换2. 批量转换Word文件三、工具特性分析优点局

Python中4大日志记录库比较的终极PK

《Python中4大日志记录库比较的终极PK》日志记录框架是一种工具,可帮助您标准化应用程序中的日志记录过程,:本文主要介绍Python中4大日志记录库比较的相关资料,文中通过代码介绍的非常详细,... 目录一、logging库1、优点2、缺点二、LogAid库三、Loguru库四、Structlogphp

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra