面向对象之元类

什么是元类

在python中,想必__init__,大家基本都知道,然后再有一部分人知道__new__,再到元类,知道的就更少了些了。那么,什么是元类🤔

元类,官方的定义是,类的类型。而类型的顶点,便是type。

metaclass - The class of a class. Class definitions create a class name, a 
class dictionary, and a list of base classes. The metaclass is responsible for 
taking those three arguments and creating the class. Most object oriented programming languages provide a default implementation. What makes 
Python special is that it is possible to create custom metaclasses. Most users 
never need this tool, but when the need arises, metaclasses can provide 
powerful, elegant solutions. They have been used for logging attribute 
access, adding thread-safety, tracking object creation, implementing 
singletons, and many other tasks.

上面的内容大致写的是:元类,是类的类型。然后定义了name(类的名称),dict(可用于传入一些内置参数),bases(包含所有父类的列表)。然后猿类可以根据些参数创建一个类。然后就是一些元类的用途,用于记录属性的获取、确保线程安全、跟踪对象的创建、实现单例模式,等等。

实例分析

父子关系分析

仅仅通过描述,似乎不是很好理解。于是整了些小实验:效果如下:

>>> object.__base__
>>> type.__base__
<class 'object'>
>>> type.__class__
<class 'type'>
>>> object.__class__
<class 'type'>

先看父子关系,我们可以看到:
object没有父类,而type的父类是object。
因此,我们可以得出object是父类的顶点。

再看类型,同理:
object的类型是type,type的类型也是type。
因此,type是类型的顶点。但是,为什么object的类型也是type呢。所以我们的结论是,type是基于object实现的,而基于object实现的type实现的type被定义为了类型的顶点。

元类的用途

动态且快速地创建一个类

>>> t = type("test",(),{"a":0})
>>> t.a
0
>>> t
<class '__main__.test'>

追踪对象的创建

当然,在追踪的同时,我们也可以做一些事情,比如对属性的大小写做限制。

class UpperAttrMetaclass(type):
    def __new__(cls, name, bases, dct):
        uppercase_attrs = {}
        for attr_name, attr_value in dct.items():
            if not attr_name.startswith('__'):
                uppercase_attrs[attr_name.upper()] = attr_value
            else:
                uppercase_attrs[attr_name] = attr_value

        # 使用修改后的属性创建新的类
        return super().__new__(cls, name, bases, uppercase_attrs)

# 使用 UpperAttrMetaclass 元类创建一个新类
class MyClass(metaclass=UpperAttrMetaclass):
    my_attr = "hello"

# 测试 MyClass 中的属性名是否已转换为大写
obj = MyClass()
print(obj.MY_ATTR)  # 输出: hello

经过测试发现,new__函数的的cls对象变量创建会经过以下逻辑:
1、当前类有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为当前类的main函数类对象)
2、如果Python没有找到__metaclass
,它会继续在父类中寻找__metaclass__属性,并尝试做和前面同样的操作
3、如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作
4、如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。

这也就是为什么,我们在用type不传参时,与不传metaclass参数时会得到类似的报错信息。判断type类的__call__逻辑是三个参数时,调用__new__函数创建实例。这也就符合了,我们上方的逻辑,type所有类型的顶点,所有的实例都是基于type的实例创建的。

实现单例模式(本质上利用了闭包思想)

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class MyClass(metaclass=Singleton):
    pass

obj1 = MyClass()
obj2 = MyClass()
print(obj1 is obj2)  # 输出: True

实际案例

Django框架中的ORM(对象关系映射)

Django使用元类来创建数据库模型类和数据库表之间的映射关系。通过定义模型类并使用特定的元类,Django能够自动创建数据库表结构,以及提供方便的API来进行数据库操作。

类型检查和验证

一些类型检查工具和框架使用元类来验证代码中的类型注解和类型约束。通过拦截类的创建过程,元类可以检查类的属性和方法是否符合类型注解的要求,并提供类型安全性。

自动化API绑定

某些框架和工具使用元类来自动生成API绑定代码。通过定义特定的元类,可以在运行时自动创建API绑定,并提供便捷的接口来访问和调用函数和方法。

插件系统

元类可用于创建插件系统,允许开发人员针对现有类进行扩展或修改。通过定义一个元类,可以在运行时将插件应用到类上,并在类定义时自动应用插件的功能。

序列化和反序列化

某些序列化库使用元类来自动地将对象转换为序列化格式(如JSON、XML等),以及将序列化数据反序列化为对象。通过定义特定的元类,可以控制对象的序列化和反序列化过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/586412.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据组件之Storm详解

Storm 是一个免费并开源的分布式实时计算系统&#xff0c;具有高容错性和可扩展性。它能够处理无边界的数据流&#xff0c;并提供了实时计算的功能。与传统的批处理系统相比&#xff0c;Apache Storm 更适合处理实时数据。 让我们深入了解一下 Storm&#xff1a; 1.Storm 简介…

Systemback Ubuntu14.04 制作自定义系统ISO镜像

工作需要&#xff0c;要基于ubuntu自定义一些编译环境并将自己配置好的ubuntu做成镜像。 硬件准备 ​ 为保证能够顺利完成系统iso镜像的制作与系统还原&#xff0c;推荐准备一个较大容量的U盘或者移动固态硬盘&#xff0c;同时确保自己的Ubuntu系统还有比较大的可用空间。 1 S…

sgg_ssm学习--前端搭建遇到的问题

目录 问题1&#xff1a;由于我是解压缩软件nodejs&#xff0c;没有添加系统路径 解决&#xff1a;添加nodejs的路径 到系统 path中 问题2&#xff1a;vscode 终端输入npm命令 报错 解决(如图所示在vscode打开前端工程&#xff0c;终端修改如下配置)&#xff1a; 问题1&…

CSS 伪类、伪元素的应用实例:电池充电、高能进度条

一、目的 本文通过 CSS 伪类、伪元素&#xff0c;结合动画 animation 和 Vue 动态样式属性&#xff08;通过 CSS 变量&#xff09;的写法&#xff0c;来实现电池充电、高能进度条的效果&#xff0c;如下图所示。 二、基础知识 1、CSS 伪类、伪元素 简单概括成以下 4 点&#x…

如何提升制造设备文件汇集的可靠性和安全性?

制造设备文件汇集通常指的是将与制造设备相关的各种文档和资料进行整理和归档的过程。这些文件可能包括但不限于&#xff1a; 生产数据&#xff1a;包括生产计划、订单信息、生产进度等。 设计文件&#xff1a;如CAD图纸、设计蓝图、产品模型等。 工艺参数&#xff1a;用于指…

新唐的nuc980/nuc972的开发1-环境和源码同步

开发环境安装 1.1更新源 服务器端&#xff1a;可以参考&#xff1a;Linux替换清华源_更改清华源-CSDN博客 下面是桌面端的方法&#xff1a; 打开系统的软件中心&#xff0c;选择自己想要使用的源 更新缓存 1.2安装必须的库 apt-get install patch apt-get install libc6-dev …

ClickHouse高原理与实践

ClickHouse高原理与实践 1 ClickHouse的特性1.1. OLAP1.2. 列式存储1.3. 表引擎1.4. 向量化执行1.5. 分区1.6. 副本与分片1.7 其他特性 2. ClickHouse模块设计2.1 Parser分析器与Interpreter解释器2.2 Storage2.3 Column与Field2.4 DataType2.5 Block2.6 Cluster与Replication …

数据库基础--MySQL简介以及基础MySQL操作

数据库概述 数据库&#xff08;DATABASE&#xff0c;简称DB&#xff09; 定义:是按照数据结构来组织、存储和管理数据的仓库.保存有组织的数据的容器(通常是一个文件或一组文件) 数据库管理系统(Database Management System,简称DBMS) 专门用于管理数据库的计算机系统软件;…

机器学习:深入解析SVM的核心概念【一、间隔与支持向量】

直接阅读原始论文可能有点难和复杂&#xff0c;所以导师直接推荐我阅读周志华的《西瓜书》&#xff01;&#xff01;然后仔细阅读其中的第六章&#xff1a;支持向量机 间隔与支持向量 **问题一&#xff1a;什么叫法向量&#xff1f;为什么是叫法向量**什么是法向量&#xff1f;…

c#数据库: 10.调用存储过程查询信息,并显示在窗体上

查询女生信息&#xff0c;并将信息显示在窗体上: 原数据表//右键数据库名,新建查询 ------------- 新建查询窗口,添加新建存储过程Procedure_GetGirls1和查询代码如下 : CREATE PROCEDURE dbo.Procedure_GetGirls1 /*存储过程名称*/ AS SELECT * f…

如何通过前后端交互的方式制作Excel报表

前言 Excel拥有在办公领域最广泛的受众群体&#xff0c;以其强大的数据处理和可视化功能&#xff0c;成了无可替代的工具。它不仅可以呈现数据清晰明了&#xff0c;还能进行数据分析、图表制作和数据透视等操作&#xff0c;为用户提供了全面的数据展示和分析能力。 今天小编就…

2024年武汉东湖高新水测成绩出来了

本次水测通过人员有1016名&#xff0c;通过的人数还是蛮多的&#xff0c;水测其实没有大家想象的那么难&#xff0c;现在职称评审都是水测线下评审的模式进行的。 水平测试分机考&#xff0c;笔试和面试答辩&#xff0c;各区随机安排选其一&#xff0c;机考就相当于考驾照刷题&…

HTML:元素分类

HTML&#xff1a;元素分类 概述块级元素&#xff08;Block-level Elements&#xff09;内联元素&#xff08;Inline Elements&#xff09;替换元素&#xff08;Replaced Elements&#xff09;表单元素&#xff08;Form Elements&#xff09; 概述 HTML&#xff08;HyperText M…

如何使用Spring Boot导出数据到Excel表格

在开发应用程序时&#xff0c;经常会遇到将数据导出到Excel表格的需求。Spring Boot提供了简单而有效的方法来实现这个功能。本文将介绍如何使用Spring Boot和Apache POI库将数据导出到Excel表格&#xff0c;并提供一个示例代码来演示该过程。 1. 准备工作 首先&#xff0c;确…

从Paint 3D入门glTF

Paint 3D Microsoft Paint 3D是微软的一款图像编辑软件&#xff0c;它是传统的Microsoft Paint程序的升级版。 这个新版本的Paint专注于三维设计和创作&#xff0c;使用户可以使用简单的工具创建和编辑三维模型。 Microsoft Paint 3D具有直观的界面和易于使用的工具&#xff0…

C语言入门课程学习笔记-7

C语言入门课程学习笔记-7 第31课 - 初探程序中的函数实验-函数调用实验-函数求前n个正整数和 第32课 - 深入浅出函数调用第33课 - 函数定义细节剖析实验-返回int实验-返回void 第34课 - 函数参数深度剖析实验-形参实参实验-数组元素作为函数形参小结 第35课 - 编写函数对数组排…

WebAuthn 无密码身份认证

文章目录 WebAuthn简介工作原理组成部分架构实现注册认证应用场景案例演示 WebAuthn简介 WebAuthn&#xff0c;全称 Web Authentication&#xff0c;是由 FIDO 联盟&#xff08;Fast IDentity Online Alliance&#xff09;和 W3C&#xff08;World Wide Web Consortium&#x…

cisp证有用吗?

CISP证书肯定是有用的&#xff01;就像你说的&#xff0c;少一个证不如多一个证&#xff0c;总比“证到用时方恨少”的好&#xff01;既然你想往网络安全方向发展&#xff0c;考个CISP还是有必要的&#xff0c;CISP目前考试比较简单&#xff0c;拿证书还是比较容易的&#xff0…

【天龙怀旧服】攻略day8

关键字&#xff1a; 高血祭学习、角色伤害、幻魂升级 1】高血祭学习是否需要花费99金 珍兽手动技能分为分开阳类/破军类 高血祭属于开阳类 当已学会开阳类&#xff08;如肉墙&#xff09;学习高血祭&#xff0c;仅需1.70金&#xff0c;属于替换 而已学会破军类&#xff08;…

GitLab常用指令!(工作中常用的)

目录 克隆代码创建分支切换分支将代码提交到分支当中Merge合并 克隆代码 复制完地址&#xff0c;打开Git Bash&#xff0c;然后 git clone “复制的地址”创建分支 创建new_test分支 git branch new_test切换分支 切换到new_test分支 git checkout new_test将代码提交到分…
最新文章