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 详解
元类(metaclass)是 Python 中一个高级且相对较少使用的概念。元类可以被视为类的类,它控制类的创建过程。 一、基本概念 在 Python 中,一切皆对象。为了避免混淆,我们约定两个术语: 类实例:当…...

HCIA基础知识
IP地址、静态路由、动态路由、交换机 OSPF RIP DHCP VLAN ACL NAT OSI TCP/IP UDP TCP 三次握手,四次挥手,报头 什么是网络? 由网络连接设备通过传输介质将网络终端设备连接起来,进行资源共享、信息传递的平台。 OSI七…...

翻译: Streamlit从入门到精通 部署一个机器学习应用程序 四
Streamlit从入门到精通 系列: 翻译: Streamlit从入门到精通 基础控件 一翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二翻译: Streamlit从入门到精通 构建一个机器学习应用程序 三 1. 5. 如何部署一个Streamlit应用 部署是将应用程序从开发…...

AI时代Python量化交易实战:ChatGPT引领新时代
文章目录 《AI时代Python量化交易实战:ChatGPT让量化交易插上翅膀》关键点内容简介作者简介购买链接 《AI时代架构师修炼之道:ChatGPT让架构师插上翅膀》关键点内容简介作者简介 赠书活动 《AI时代Python量化交易实战:ChatGPT让量化交易插上翅…...

国科大软件安全原理期末复习笔记
1 软件安全总论 1.软件的三大特性:复杂性、互连性、可扩展性; 2.基本概念:缺陷、漏洞、风险 缺陷(bug):软件在设计和实现上的错误;漏洞(vulnerability):漏洞…...

人工智能软件测试2024年主要趋势
人工智能软件测试领域在未来可能面临多个发展趋势,其中一些趋势可能会对测试方法、工具和流程产生深远的影响。以下是塑造人工智能软件测试未来的主要趋势: 自动化和自动学习测试:随着人工智能的发展,测试自动化将变得更加智能和自…...

【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
🍎个人博客:个人主页 🏆个人专栏:JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 懒汉式(Lazy Initialization): 双重检查锁定(Double-Checked Locking)…...

常见的反爬虫风控 | 验证码风控
一.前言 在当今信息技术迅速发展的背景下,网站和在线服务面临着日益增长的自动化访问威胁,这些大多来自于各类爬虫程序。这种大量的自动化访问不仅对网站的正常运行构成压力,还可能导致敏感数据的泄露,甚至被用于不正当竞争和恶意…...
ClickHouse(21)ClickHouse集成Kafka表引擎详细解析
文章目录 Kafka表集成引擎配置Kerberos 支持 虚拟列 资料分享参考文章 Kafka表集成引擎 此引擎与Apache Kafka结合使用。 Kafka 特性: 发布或者订阅数据流。容错存储机制。处理流数据。 老版Kafka集成表引擎参数格式: Kafka(kafka_broker_list, kaf…...

JSP-概念
一、引子 很多读者可能听过JSP,并且知道这是一门过时的技术了。在Spring,SpringBoot已经成为主流的今天,笔者为什么还要介绍JSP的相关内容呢?笔者常常提到一个概念:理解一门技术,要理解这个技术为什么产生…...
sqlite插入语句id自增列问题
sqlite给主键id设置AUTOINCREMENT自增在插入数据的时候报错table has x columns but x-1 values were supplied 为什么自增列要显示不提供,sqlite需要提供自增列table ResTools has 7 columns but 6 values were supplied SQL Statement:insert into ResTools values(管理系统w…...

C#,字符串匹配(模式搜索)AC(Aho Corasick)算法的源代码
Aho-Corasick算法简称AC算法,也称为AC自动机(Aho-Corasick)算法,1975年产生于贝尔实验室(The Bell Labs),是一种用于解决多模式字符串匹配的经典算法之一。 the Bell Lab 本文的运行效果: AC算法以模式树…...

【网络取证篇】Windows终端无法使用ping命令解决方法
【网络取证篇】Windows终端无法使用ping命令解决方法 以Ping命令为例,最近遇到ping命令无法使用的情况,很多情况都是操作系统"环境变量"被改变或没有正确配置导致—【蘇小沐】 目录 1、实验环境(一)无法ping命令 &a…...

electron+vue网页直接播放RTSP视频流?
目前大部分摄像头都支持RTSP协议,但是在浏览器限制,最新版的浏览器都不能直接播放RTSP协议,Electron 桌面应用是基于 Chromium 内核的,所以也不能直接播放RTSP,但是我们又有这个需求怎么办呢? 市场上的方案…...
【Delphi 基础知识 19】Assigned的用法
在Delphi中,Assigned 是一个用于检查指针是否已分配内存的函数。它通常用于检查对象或指针是否已经被分配内存,以避免在未分配内存的情况下引用或操作它。 以下是 Assigned 的一些用法示例: 检查对象是否已分配内存: varMyObject…...
多线程在编程中的重要性有什么?并以LabVIEW为例进行说明
多线程在编程中的重要性体现在以下几个方面: 并行处理: 多线程允许程序同时执行多个任务,这在现代多核心处理器上尤其重要。通过并行处理,可以显著提高程序的执行效率和响应速度。 资源利用最大化: 通过多线程&#x…...
K8S---kubectl top
一、简介 该命令类似于linux–top命令,用于显示node和pod的CPU和内存使用情况 二、命令行 1、help命令 k top --help Display resource (CPU/memory) usage. The top command allows you to see the resource consumption for nodes or pods. This command requires Metri…...
Linux部署前后端项目
部署SpringBoot项目 创建SpringBoot项目 先确保有一个可以运行的springboot项目,这里就记录创建项目的流程了,可以自行百度。 命令行启动 2.1、在linux中,我是在data目录下新创建的一个project目录(此目录创建位置不限制&…...

一文搞懂系列——Linux C线程池技术
背景 最近在走读诊断项目代码时,发现其用到了线程池技术,感觉耳目一新。以前基本只是听过线程池,但是并没有实际应用。对它有一丝的好奇,于是趁这个机会深入了解一下线程池的实现原理。 线程池的优点 线程池出现的背景…...

stable diffusion代码学习笔记
前言:本文没有太多公式推理,只有一些简单的公式,以及公式和代码的对应关系。本文仅做个人学习笔记,如有理解错误的地方,请指出。 本文包含stable diffusion入门文献和不同版本的代码。 文献资源 本文学习的代码&…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...