【python】魔术方法大全——基础篇

什么是魔术方法

image.png

所谓魔法方法,它的官方的名字实际上叫special method,是Python的一种高级语法,允许你在类中自定义函数,并绑定到类的特殊方法中。比如在类A中自定义__str__()函数,则在调用str(A())时,会自动调用__str__()函数,并返回相应的结果。

docs.python.org/3/reference…

我们常常看到的Magic Methods这个名字,在官方的文档里是没有出现过的。

当然无论是magic methods还是魔术方法,这些词都被广泛的使用着。

所谓的魔术方法,是python提供的,让用户客制化一个类的方式,它顾名思义,就是定义在类里面的一些特殊的方法。 这些special method的特点,就是它的method的名字前后都有两个下划线,所以这些方法也被称为dunder methods。那包括这种前后两个下划线的形式,也叫做dunder score,它的意思就是double underscore

在我们平时写程序的时候,已经或多或少的接触过不少的魔术方法。
比如:__init__就非常非常的常用。

image.png

基础的魔术方法

__new__和__init__

首先,我们来聊一下__new____init__。 这两个方法,可以让你改变从一个类建立一个对象时候的行为,这两个也比较容易被搞混。 如果你不那么了解这两个方法的机制本身,你只需要记住,__new__是从一个class建立一个object的过程。 而__init__是有了这个object之后,给这个object初始化的过程。

class A:def __new__(cls, *args, **kwargs):print("__new__")return super().__new__(cls, *args, **kwargs)def __init__(self):print("__init__")if __name__ == '__main__':a = A()

输出结果为:

__new__
__init__

我们可以看到__new____init__都被使用了。我们可以粗略的想象成:

obj = __new__(A)
__init__(obj)

如果我们在建立object的时候传入了参数,则参数既会传给__new__,也会传给__init__。 在我们实际的应用中,__new__函数用到的是相对较少的。如果你不需要客制化建立这个object的过程,你只需要初始化这个object,你只需要用到__init__

那什么时候用__new__呢?

比如说,我要创建一个单例,或者一些和metaclass有关的才会用到__new__函数。

单例模式是指在整个应用程序中,某个类只能有一个实例存在,且该实例可以被任何模块访问到。这种模式的应用场景包括数据库连接池、日志对象等需要全局唯一性的对象。

简单单例

以下是一个简单的单例模式的示例代码:

class Singleton:_instance = Nonedef __new__(cls):if not cls._instance:cls._instance = super().__new__(cls)return cls._instance

在这个例子中,我们定义了一个名为 Singleton 的类。它包含一个类变量 _instance,该变量用于存储唯一实例的引用。

__new__ 方法中,我们检查 _instance 是否为 None。如果是,则创建一个新的实例并将其分配给 _instance。如果不是,则直接返回 _instance,而不创建新的实例。

通过这种方式,我们可以确保在应用程序中只有一个 Singleton 实例。要使用它,只需创建一个 Singleton 对象即可:

s1 = Singleton()
s2 = Singleton()print(s1 is s2) # 输出 True

以上代码输出结果为 True,说明 s1s2 引用的是同一个实例,即单例模式实现成功。

__new__和元类(metaclass)

在 Python 中,__new__() 和元类(metaclass)之间有着紧密的联系,它们都是用来控制类的创建过程的。

元类是 Python 中的一个高级特性,它允许我们在创建类的过程中动态地修改类。元类可以通过定义 __new__() 方法来控制类的实例化过程。

在 Python 中,当我们通过 class 关键字定义一个新的类时,Python 解释器会自动调用元类来实例化类对象。元类在实例化类对象之前,先调用类的 __new__() 方法来创建类的实例,然后再调用 __init__() 方法来初始化实例。

在 Python 中,使用 __call__() 方法可以实现将类的实例对象作为函数调用的效果,类似于调用一个函数。当我们调用一个类的实例对象时,Python 会自动调用这个实例对象的 __call__() 方法,从而实现了将类的实例对象作为函数调用的效果。

通过在类的 __call__() 方法中间接调用类的 __new__() 方法和 __init__() 方法,可以实现单例模式。具体而言,每次调用类的实例对象时,都会先检查已经创建的实例对象是否存在,如果存在则直接返回该实例对象,如果不存在则通过调用 __new__() 方法和 __init__() 方法来创建一个新的实例对象,并将其存储下来。由于每次都返回同一个实例对象,因此实现了单例模式。

以下是一个使用元类和 __call__() 方法实现单例模式的示例代码:

class SingletonType(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=SingletonType):pass

在上述代码中,我们首先定义了一个元类 SingletonType,这个元类重写了 __call__() 方法,用于控制类的实例化过程。在 __call__() 方法中,我们首先检查 _instances 字典中是否已经有该类的实例对象,如果已经存在,则直接返回该实例对象;如果不存在,则通过调用父类的 __call__() 方法创建一个新的实例对象,并将其存储到 _instances 字典中,然后返回该实例对象。

接下来,我们定义了一个类 SingletonClass,并将其元类设置为 SingletonType。由于 SingletonType__call__() 方法控制着 SingletonClass 的实例化过程,因此每次创建 SingletonClass 的实例对象时,都会经过 SingletonType__call__() 方法来进行处理,从而实现了单例模式。

下面是一个示例,演示了如何使用 SingletonClass 类来创建实例:

a = SingletonClass()
b = SingletonClass()print(a is b)  # True

由于 SingletonClass 类是一个单例类,因此 ab 都是同一个实例对象,所以 a is b 的结果为 True

所以必要时,我们可以通过元类和__new__方法来控制类的创建过程。

__new__是创建object,因此它是有返回值的,必须返回这个object。
__init__没有返回值, __init__函数里面的self就是你要初始化的对象。

__del__

__del__()是delete的缩写,这是析构魔术方法。当一块空间没有了任何引用时 默认执行__del__回收这个类地址,一般我们不自定义__del__, 有可能会导致问题

  • 触发时机:当对象被内存回收的时候自动触发,有下面两种情况:

    1. 页面执行完毕回收所有变量
    2. 当多个对象指向同一地址,所有对象被del的时候
  • 功能:对象使用完毕后资源回收

  • 参数:一个self接受对象

  • 返回值:无

注意:程序自动调用__del__()方法,不需要我们手动调用。

image.png python中对象的释放是比较复杂的。 __del__和关键字del是没有关系的,我们看到del o没有触发__del____del__()del关键字是两个不同的概念,虽然它们都与对象的销毁相关。

del是Python的一个关键字,用于删除变量或对象的引用。当我们执行del obj语句时,Python会将对象obj的引用计数减1,如果引用计数为0,则对象被销毁。del关键字并不会直接调用对象的__del__()方法,它只是将对象的引用计数减1,由Python自动决定是否调用__del__()方法。

__del__()方法是一个特殊方法,用于在对象被销毁时执行一些清理任务。当对象的引用计数为0时,Python会自动调用该对象的__del__()方法进行清理。__del__()方法在对象被销毁前最后一次被调用,我们可以在这个方法中执行一些需要进行清理的操作,如释放资源、关闭文件等。

需要注意的是,__del__()方法不是必须的,大多数情况下,Python会自动处理对象的销毁和内存管理,我们不需要手动定义__del__()方法。如果我们确实需要进行一些特殊的清理任务,应该尽量避免使用__del__()方法,而是使用上下文管理器、with语句等方式来管理资源和清理任务。

__repr__和__str__

__repr__(self)__str__(self)都是用于返回对象的字符串表示形式,但它们的用途不同。__repr__(self)主要用于调试和开发,而__str__(self)则主要用于用户友好的输出。 举个例子,考虑下面的Python类:

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f"Person(name={self.name}, age={self.age})"def __str__(self):return f"{self.name} is {self.age} years old"

在这个例子中,__repr__返回一个类似于构造函数调用的字符串,用于显示对象的内部状态。而__str__则返回一个可读的字符串,用于显示对象的外部状态。例如:

>>> person = Person("Alice", 25)
>>> print(person)  # 调用 __str__
Alice is 25 years old
>>> person  # 调用 __repr__
Person(name=Alice, age=25)

这样,在调试和开发时,我们可以使用__repr__方法来查看对象的内部状态,而在用户友好的输出中使用__str__方法来提供易于理解的字符串表示形式。

在实际使用中,我们可以通过内置函数repr()str()来分别获取对象的__repr____str__表示形式。例如:

p = Person("Alice", 25)
print(repr(p))  # Person('Alice', 25)
print(str(p))   # Alice (25 years old)
  • __repr__()__str__()的“备胎”,如果找不到__str__()就会找__repr__()方法。
  • %r默认调用的是__repr__()方法,%s调用__str__()方法

__formate__

__format__方法是Python中用于格式化对象输出的特殊方法。它可以让我们在使用字符串格式化方法(如str.format()f-string等)输出对象时自定义输出格式。

__format__方法有两个参数,分别为格式字符串和格式参数。格式字符串用于指定输出格式,格式参数则是要输出的参数值。其中,格式字符串是一个包含格式说明符的字符串,可以使用大括号{}来指定要输出的参数,并在大括号中使用冒号:来指定参数的格式。

下面是一个简单的例子,展示如何在类中定义__format__方法来控制输出格式:

class Point:def __init__(self, x, y):self.x = xself.y = ydef __format__(self, format_spec):if format_spec == "r":return f"({self.y}, {self.x})"else:return f"({self.x}, {self.y})"p = Point(1, 2)
print("Formatted point: {:r}".format(p))

在上面的例子中,我们定义了一个Point类,包含xy两个属性。我们在类中定义了__format__方法,用于控制输出格式。如果格式字符串为"r",则输出(y, x)的格式;否则输出(x, y)的格式。在最后一行,我们使用str.format()方法并传入"!r"参数来触发__format__方法,输出结果为Formatted point: (2, 1)

需要注意的是,如果我们定义了__format__方法,但在格式字符串中没有使用相应的格式说明符,那么__format__方法将不会被调用。此外,我们还可以在类中定义其他特殊方法来控制对象的输出格式,例如__str____repr__等。

如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓
Python全套学习资料

在这里插入图片描述

1️⃣零基础入门

① 学习路线

对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~
在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述

2️⃣国内外Python书籍、文档

① 文档和书籍资料

在这里插入图片描述

3️⃣Python工具包+项目源码合集

①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
在这里插入图片描述

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

4️⃣Python面试题

我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

5️⃣Python兼职渠道

而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。
在这里插入图片描述

上述所有资料 ⚡️ ,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL笔记-第12章_MySQL数据类型精讲

视频链接:【MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板】 文章目录 第12章_MySQL数据类型精讲1. MySQL中的数据类型2. 整数类型2.1 类型介绍2.2 可选属性2.2.1 M2.2.2 UNSIGNED2.2.3 ZEROFILL 2.3 适用场景2.4…

希亦|鲸立|小吉内衣洗衣机好用吗?强势PK“洗护一体”王者!

随着人们的生活水平的提升,越来越多小伙伴来开始追求更高的生活水平,一些智能化的小家电就被发明出来,而且内衣洗衣机是其中一个。我们对内衣裤的清洗频次会高于普通衣服,大多数人会选择手洗内衣裤,都在手洗过程不仅会…

Live800:企业做好客服质检的5大方法

在现代商业社会中,客服质量已经成为了企业竞争力的重要组成部分。一家企业的客服质量直接关系到其品牌形象和客户满意度,因此企业必须要重视客服质量,并且采取一些有效的方法来做好客服质检。下面将介绍企业做好客服质检的5大方法。 一、建立…

HI3559AV100和FPGA 7K690T的PCIE接口调试记录

1、基本情况 HI3559AV100和690t之间使用pcie2.0 x2接口连接,3559作为RC端,690T作为EP端,驱动使用XDMA。系统主要功能是FPGA采集srio接口过来的图像数据,再通过pcie把数据传递给3559,3559再实现图像数据的存储、AI处理、…

HarmonyOS鸿蒙应用开发——数据持久化Preferences

文章目录 数据持久化简述基本使用与封装测试用例参考 数据持久化简述 数据持久化就是将内存数据通过文件或者数据库的方式保存到设备中。HarmonyOS提供两两种持久化方案: Preferences:主要用于保存一些配置信息,是通过文本的形式存储的&…

面试必备的Linux常用命令

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 Linux常用命令 1、文件及内容2、网络3、进程服务4、…

【FPGA】综合设计练习题目

前言 这是作者这学期上的数电实验期末大作业的题目,综合性还是十分强的,根据组号作者是需要做“4、篮球比赛计分器”,相关代码会在之后一篇发出来,这篇文章用于记录练习题目,说不定以后有兴趣或者有时间了回来做做。 …

慢SQL的治理经验

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、慢SQL导致的后果 二、可能导致慢SQL的原因 三、如何发现慢SQL 3.1 JVM Sandbox 四、识别高危SQL 4.1 阿里的重点强制SQL规…

微信小程序ios中非cover组件点击重复触发地图tap事件

现象&#xff1a; map中使用view组件的click事件会重复触发地图的tap组件&#xff0c;只在ios上出现 <map id"maps" style"width: 100vw;height: 100vh;" :latitude"latitude" :longitude"longitude":markers"markers"…

element-ui以服务方式调用loading,自定义修改icon

一、以服务的方式调用Loading 除了常用的v-loading、this.$loading我们还可以以服务的方式调用。主要有以下步骤 引入Loading服务 import { Loading } from element-ui;在需要时调用 Loading.service(options);其中 options 参数为 Loading 的配置项&#xff0c;具体见下表…

(第8天)保姆级 PL/SQL Developer 安装与配置

PL/SQL Developer 安装与配置(第8天) 咱们前面分享了很多 Oracle 数据库的安装,但是还没有正式使用过 Oracle 数据库,怎么连接 Oracle 数据库?今天就来讲讲我学习中比较常用的 Oracle 数据库连接工具:PL/SQL DEVELOPER。 PL/SQL Developer 的安装和配置对于新手来说还是…

Unity 射线检测(Raycast)检测图层(LayerMask)的设置

目录 主要内容 拓展&#xff1a; 主要内容 Raycast函数有很多重载(函数的重载根据函数的参数来决定) 这里只涉及这个重载,其余重载可以很方便得在Visual Studio中看源码获取&#xff1b; public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hit…

链游成为蓝海,潮游世界开创未来新时代

区块链、元宇宙浪潮来袭&#xff0c;为数字世界开启崭新的大门&#xff0c;一场链游模式的范式革命正在发生&#xff01; 未来&#xff0c;元宇宙中&#xff0c;链游将成为中坚力量。 潮游世界抢占时代先机&#xff0c;利用区块链技术的去中心化和数字资产的不可替代性&#x…

设计原则 | 接口隔离原则

一、接口隔离原则 1、原理 客户端不应该依赖它不需要的接口&#xff0c;即一个类对另一个类的依赖应该建立在最小的接口上。如果强迫客户端依赖于那些它们不使用的接口&#xff0c;那么客户端就面临着这个未使用的接口的改变所带来的变更&#xff0c;这无意间导致了客户程序之…

【MySQL】MySQL库的操作

MySQL库的操作 一、创建数据库创建数据库案例字符集和校验规则校验规则对数据库的影响 二、操纵数据库1、查看数据库2、查看当前正在使用的数据库3、使用数据库4、显示创建语句5、数据库删除6、数据库的修改7、备份和恢复8、查看连接情况 一、创建数据库 创建数据库的语法如下…

计网 - TCP扫盲

文章目录 知识点TCP头格式TCP有限状态机&#xff08;FSM&#xff09;为何需要TCP协议TCP的定义TCP连接的概念如何唯一确定一个TCP连接TCP vs UDPTCP拥塞控制TCP流量控制 导图 知识点 TCP头格式 TCP头部包含多个字段&#xff0c;其中一些是必需的&#xff0c;而另一些是可选的…

MySQL笔记-第18章_MySQL8其它新特性

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第18章_MySQL8其它新特性1. MySQL8新特性概述1.1 MySQL8.0 新增特性1.2 MySQL8.0移除的旧特性 2. 新特性1&#xff1a;窗口函数2.1 使用窗口…

数据结构实验任务八:排序算法的实现与分析

问题描述 统计成绩&#xff1a;给出 n 个学生的考试成绩表&#xff0c;每条信息由姓名和分数组成&#xff0c;试设 计一个算法&#xff1a; 1.按分数高低次序&#xff0c;打印出每个学生在考试中获得的名次&#xff0c;分数相同的为同 一名次&#xff1b; 2.按名次列出每个学生…

性能优化 vue2/vue3 通过CDN 减少项目启动时间

其实更多可以通过压缩图片等文件大小 也会让项目运行快一些 以及尽量使用异步或者懒加载 使用CDN可以避免在项目中使用npm导入Vue的依赖项&#xff0c;从而减少项目启动时的加载时间 使用方法如下 <!-- Vue 2 --> <script src"https://cdn.jsdelivr.net/npm/vue…

解码大语言模型奥秘:《大规模语言模型:从理论到实践》震撼上市!

2022年11月&#xff0c;ChatGPT的问世展示了大模型的强大潜能&#xff0c;对人工智能领域有重大意义&#xff0c;并对自然语言处理研究产生了深远影响&#xff0c;引发了大模型研究的热潮。 距ChatGPT问世不到一年&#xff0c;截至2023年10月&#xff0c;国产大模型玩家就有近2…