当前位置: 首页 > news >正文

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 详解

元类&#xff08;metaclass&#xff09;是 Python 中一个高级且相对较少使用的概念。元类可以被视为类的类&#xff0c;它控制类的创建过程。 一、基本概念 在 Python 中&#xff0c;一切皆对象。为了避免混淆&#xff0c;我们约定两个术语&#xff1a; 类实例&#xff1a;当…...

HCIA基础知识

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

翻译: Streamlit从入门到精通 部署一个机器学习应用程序 四

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

AI时代Python量化交易实战:ChatGPT引领新时代

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

国科大软件安全原理期末复习笔记

1 软件安全总论 1.软件的三大特性&#xff1a;复杂性、互连性、可扩展性&#xff1b; 2.基本概念&#xff1a;缺陷、漏洞、风险 缺陷&#xff08;bug&#xff09;&#xff1a;软件在设计和实现上的错误&#xff1b;漏洞&#xff08;vulnerability&#xff09;&#xff1a;漏洞…...

人工智能软件测试2024年主要趋势

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

【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 懒汉式&#xff08;Lazy Initialization&#xff09;&#xff1a; 双重检查锁定&#xff08;Double-Checked Locking&#xff09;…...

常见的反爬虫风控 | 验证码风控

一.前言 在当今信息技术迅速发展的背景下&#xff0c;网站和在线服务面临着日益增长的自动化访问威胁&#xff0c;这些大多来自于各类爬虫程序。这种大量的自动化访问不仅对网站的正常运行构成压力&#xff0c;还可能导致敏感数据的泄露&#xff0c;甚至被用于不正当竞争和恶意…...

ClickHouse(21)ClickHouse集成Kafka表引擎详细解析

文章目录 Kafka表集成引擎配置Kerberos 支持 虚拟列 资料分享参考文章 Kafka表集成引擎 此引擎与Apache Kafka结合使用。 Kafka 特性&#xff1a; 发布或者订阅数据流。容错存储机制。处理流数据。 老版Kafka集成表引擎参数格式&#xff1a; Kafka(kafka_broker_list, kaf…...

JSP-概念

一、引子 很多读者可能听过JSP&#xff0c;并且知道这是一门过时的技术了。在Spring&#xff0c;SpringBoot已经成为主流的今天&#xff0c;笔者为什么还要介绍JSP的相关内容呢&#xff1f;笔者常常提到一个概念&#xff1a;理解一门技术&#xff0c;要理解这个技术为什么产生…...

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算法&#xff0c;也称为AC自动机(Aho-Corasick)算法&#xff0c;1975年产生于贝尔实验室&#xff08;The Bell Labs&#xff09;&#xff0c;是一种用于解决多模式字符串匹配的经典算法之一。 the Bell Lab 本文的运行效果&#xff1a; AC算法以模式树…...

【网络取证篇】Windows终端无法使用ping命令解决方法

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

electron+vue网页直接播放RTSP视频流?

目前大部分摄像头都支持RTSP协议&#xff0c;但是在浏览器限制&#xff0c;最新版的浏览器都不能直接播放RTSP协议&#xff0c;Electron 桌面应用是基于 Chromium 内核的&#xff0c;所以也不能直接播放RTSP&#xff0c;但是我们又有这个需求怎么办呢&#xff1f; 市场上的方案…...

【Delphi 基础知识 19】Assigned的用法

在Delphi中&#xff0c;Assigned 是一个用于检查指针是否已分配内存的函数。它通常用于检查对象或指针是否已经被分配内存&#xff0c;以避免在未分配内存的情况下引用或操作它。 以下是 Assigned 的一些用法示例&#xff1a; 检查对象是否已分配内存&#xff1a; varMyObject…...

多线程在编程中的重要性有什么?并以LabVIEW为例进行说明

多线程在编程中的重要性体现在以下几个方面&#xff1a; 并行处理&#xff1a; 多线程允许程序同时执行多个任务&#xff0c;这在现代多核心处理器上尤其重要。通过并行处理&#xff0c;可以显著提高程序的执行效率和响应速度。 资源利用最大化&#xff1a; 通过多线程&#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项目&#xff0c;这里就记录创建项目的流程了&#xff0c;可以自行百度。 命令行启动 2.1、在linux中&#xff0c;我是在data目录下新创建的一个project目录&#xff08;此目录创建位置不限制&…...

一文搞懂系列——Linux C线程池技术

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

stable diffusion代码学习笔记

前言&#xff1a;本文没有太多公式推理&#xff0c;只有一些简单的公式&#xff0c;以及公式和代码的对应关系。本文仅做个人学习笔记&#xff0c;如有理解错误的地方&#xff0c;请指出。 本文包含stable diffusion入门文献和不同版本的代码。 文献资源 本文学习的代码&…...

OpenClaw+GLM-4.7-Flash:24小时运行的智能监控助手

OpenClawGLM-4.7-Flash&#xff1a;24小时运行的智能监控助手 1. 为什么需要智能监控助手&#xff1f; 去年我负责维护一个内部文档站点时&#xff0c;经常遇到半夜服务崩溃却无人知晓的情况。直到第二天同事反馈"页面打不开"&#xff0c;我才手忙脚乱地查日志、重…...

华硕笔记本终极电池拯救指南:用G-Helper实现智能充电与健康修复

华硕笔记本终极电池拯救指南&#xff1a;用G-Helper实现智能充电与健康修复 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models …...

Microsoft Agent Framework 构建 SubAgent(Multi-Agent)

本文演示如何用 Microsoft Agent Framework 用 Executor Workflow&#xff08;DAG&#xff09;模式实现 SubAgent&#xff08;子代理&#xff09;架构。通过示例代码&#xff08;来自项目的 txt&#xff09;展示并发 Fan‑Out/Fan‑In 的实现、消息路由与聚合策略&#xff0c;…...

Ludusavi:你的游戏进度守护神,三分钟搞定跨平台存档备份

Ludusavi&#xff1a;你的游戏进度守护神&#xff0c;三分钟搞定跨平台存档备份 【免费下载链接】ludusavi Backup tool for PC game saves 项目地址: https://gitcode.com/gh_mirrors/lu/ludusavi 你是否曾在电脑崩溃后&#xff0c;发现数百小时的游戏进度瞬间归零&…...

GBase 8a云数仓存算分离,“柔性搭建数仓”

传统分析型MPP数据库的搭建&#xff0c;就像装修一套毛坯房&#xff0c;从规划格局到水电改造&#xff0c;从墙面处理到家具进场&#xff0c;每一步都离不开专业师傅&#xff0c;稍有不慎就得返工重来。南大通用&#xff08;gbase database)GBase 8a云数仓&#xff08;GCDW&…...

手把手教你用LVGL特殊符号打造炫酷UI界面

手把手教你用LVGL特殊符号打造炫酷UI界面 在嵌入式设备开发中&#xff0c;UI设计往往面临资源受限的挑战。LVGL&#xff08;Light and Versatile Graphics Library&#xff09;作为一款轻量级开源图形库&#xff0c;通过其丰富的特殊符号系统&#xff0c;让开发者能够在有限资…...

制造业数据库选型实战:为什么我们从 MySQL 迁移到 TiDB

写在前面 作为一个制造业数字化团队的开发负责人&#xff0c;我最怕听到的一句话就是&#xff1a;“数据库又慢了”。 MOM 平台上线 4 年&#xff0c;数据量从最初的几百 G 涨到几个 T。每次月底报表、跨工厂查询&#xff0c;系统就开始”喘气”。加索引、拆表、优化 SQL………...

Nginx 简单使用配置

配置 user nginx; worker_processes auto;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main $remote…...

SEO_网站SEO诊断与快速优化解决办法分享

<h2>SEO诊断&#xff1a;了解你的网站现状&#xff0c;为优化铺路</h2> <p>在当今数字化时代&#xff0c;拥有一个高效、优化良好的网站是任何企业或个人成功的关键。网站SEO诊断是这一过程中的重要步骤。通过网站SEO诊断&#xff0c;我们可以全面了解你的网…...

R语言新手必看:clusterProfiler功能富集分析从安装到实战(附常见报错解决方案)

R语言实战&#xff1a;clusterProfiler功能富集分析全流程指南 第一次接触功能富集分析时&#xff0c;我被那些密密麻麻的基因列表和复杂的生物学术语搞得晕头转向。直到发现了clusterProfiler这个神器&#xff0c;它就像生物信息学分析中的瑞士军刀&#xff0c;把复杂的富集过…...