Python新姿势:用魔法方法玩转对象

文章目录

  • 前言
  • 1\. 对象构建
  • 2\. 对象属性访问
  • 3\. 对象比较
  • 4\. 对象输出
  • 5\. 对象运算
  • 6\. 总结
      • Python技术资源分享
        • 1、Python所有方向的学习路线
        • 2、学习软件
        • 3、入门学习视频
        • 4、实战案例
        • 5、清华编程大佬出品《漫画看学Python》
        • 6、Python副业兼职与全职路线


在这里插入图片描述

前言

Python中魔法方法(magic method)其实就是那些被双下划线包围的方法,比如__init____str__ 等等。

这些魔法方法添加了**“魔力”,让我们可以在面向对象编程中用更加简洁的代码来操作对象。
本篇根据面向对象编程的一些场景来介绍常用的
魔法方法**。

1. 对象构建

为了初始化对象,我们常常在对象中定义一个__init__方法,比如:

class Student(object):"""学生信息"""def __init__(self, name):print("[__init__] Student 初始化...")self.name = name# 创建对象
stu = Student("小明")# 运行结果
[__init__] Student 初始化...

当我们创建对象时,会自动调用魔法方法__init__去初始化属性。

__init__对应的是__del__,它会在对象失效的调用,
我们可以在__del__方法中清理对象Student占用的资源。

class Student(object):def __init__(self, name):print("[__init__] 初始化 Student...")self.name = namedef __del__(self):print("[__del__] 清理 Student...")def foo():print("进入 foo 函数...")stu = Student("小明")print("离开 foo 函数...")foo()# 运行结果
进入 foo 函数...
[__init__] 初始化 Student...
离开 foo 函数...
[__del__] 清理 Student...

进入 foo 函数后创建对象,离开后,自动清理对象。

2. 对象属性访问

python的对象是可以直接访问属性的,但是访问不存在的属性时,会抛出异常。

class Student(object):def __init__(self, name):print("[__init__] 初始化 Student...")self.name = namestu = Student("小明")
print(stu.name)
print(stu.fullname)# 运行结果
[__init__] 初始化 Student...
小明AttributeError: 'Student' object has no attribute 'fullname'

如果不想抛出异常,从而影响程序的其他部分的运行,
这里可以用魔法方法 __getattr__来控制访问了不存在的属性时的行为。
比如,下面的示例中,访问不存在的属性时,返回False,不抛出异常。

class Student(object):def __init__(self, name):print("[__init__] 初始化 Student...")self.name = namedef __getattr__(self, attr):print("[__getattr__] 访问了 Student 不存在的属性 {}".format(attr))return Falsestu = Student("小明")
print(stu.name)
print(stu.fullname)# 运行结果
[__init__] 初始化 Student...
小明
[__getattr__] 访问了 Student 不存在的属性 fullname
False

__getattr__相对的另一个魔法方法__setattr__,与__getattr__不同的是,它既可以设置不存在的属性,也可以设置已存在的属性。

class Student(object):def __init__(self, name):print("[__init__] 初始化 Student...")self.name = namedef __setattr__(self, attr, value):print("[__setattr__] 设置 Student 属性 {}={}".format(attr, value))self.__dict__[attr] = valuestu = Student("小明")
print(stu.name)# 已存在的属性
stu.name = "小华"
print(stu.name)# 不存在的属性
stu.fullname = "小红"
print(stu.fullname)# 运行结果
[__init__] 初始化 Student...
[__setattr__] 设置 Student 属性 name=小明
小明
[__setattr__] 设置 Student 属性 name=小华
小华
[__setattr__] 设置 Student 属性 fullname=小红
小红

每次对属性赋值,都会触发__setattr__方法,
即使在__init__中给self.name赋值,也触发了__setattr__方法,所以一共被触发了三次。

3. 对象比较

在使用基本类型(比如数值类型,字符串类型等)的时候,比较其大小非常简单。

print(1 < 2)
print(1 > 2)
print("abc" < "edf")# 运行结果
True
False
True

而对象直接互相比较大小则没有这么简单了,还是用上面的Student类,这次我们加上各门功课的分数。

class Student(object):def __init__(self, name, chinese, english, mathematics):self.name = nameself.chinese = chineseself.english = englishself.mathematics = mathematicsstu1 = Student("小明", 80, 90, 75)
stu2 = Student("小红", 85, 70, 95)# 比较两个学生对象
print(stu1 > stu2)# 运行结果
TypeError: '>' not supported between instances of 'Student' and 'Student'

不出所料,抛出了异常。
其实我们比较两个学生对象,是想要比较两个学生的总分谁高谁低。

这时,我们就可以实现用于比较的魔法方法,比如 __eq____lt____gt__等等。

class Student(object):def __init__(self, name, chinese, english, mathematics):self.name = nameself.chinese = chineseself.english = englishself.mathematics = mathematicsdef total(self):return self.chinese + self.english + self.mathematicsdef __eq__(self, other: Student):return self.total() == other.total()def __lt__(self, other: Student):return self.total() < other.total()def __gt__(self, other: Student):return self.total() > other.total()stu1 = Student("小明", 80, 90, 75)
stu2 = Student("小红", 85, 70, 95)print(stu1 > stu2)
print(stu1 == stu2)
print(stu1 < stu2)# 运行结果
False
False
True

实现相应的魔法方法,就能使用相应的比较运算符来直接比较对象了。
PS. 上面的例子中只实现了大于__gt__),等于__eq__),小于__lt__)的比较,
还有其他魔法方法,比如:大于等于__ge__),不等于__ne__),小于等于__le__)等等。
实现的方式和上面例子中类似。

4. 对象输出

对于一个基本类型的变量,显示其内容非常简单,而对于一个对象,显示的内容可能就不是我们所期望的了。

class Student(object):def __init__(self, name, chinese, english, mathematics):self.name = nameself.chinese = chineseself.english = englishself.mathematics = mathematicss = "hello world"
print(s)stu = Student("小明", 80, 90, 75)
print(stu)# 运行结果
hello world
<__main__.Student object at 0x00000164F72FD6D0>

字符串内容可以直接显示出来,而对象stu只是显示了它的内存地址,对我们了解其中的内容毫无帮助。

此时,就可以拿出我们的魔法方法__str__,来定制对象在print时显示的内容。

class Student(object):def __init__(self, name, chinese, english, mathematics):self.name = nameself.chinese = chineseself.english = englishself.mathematics = mathematicsdef __str__(self):return """姓名: {}
成绩:
1. 语文: {} 分
2. 数学: {} 分
3. 英语: {} 分""".format(self.name,self.chinese,self.mathematics,self.english,)stu = Student("小明", 80, 90, 75)
print(stu)# 运行结果
姓名: 小明
成绩:
1. 语文: 80 分
2. 数学: 75 分
3. 英语: 90 分

通过魔法方法__str__,可以让对象按照我们希望的形式显示出来。

5. 对象运算

对象除了可以像普通变量一样比较输出,是不是也可以像变量一样进行算术运算呢?
比如:

class Student(object):def __init__(self, name, scores):self.name = nameself.scores = scoresdef __str__(self):return """姓名: {}, 各科成绩: {}""".format(self.name,self.scores,)stu1 = Student("小明", [80, 90, 75])
stu2 = Student("小红", [85, 70, 95])
print(stu1)
print(stu2)
print(stu1 + stu2)# 运行结果
姓名: 小明, 各科成绩: [80, 90, 75]
姓名: 小红, 各科成绩: [85, 70, 95]TypeError: unsupported operand type(s) for +: 'Student' and 'Student'

果然,直接进行算术运算是不行的。

还是得借助魔法方法,下面在类中实现加法减法魔法方法

class Student(object):def __init__(self, name, scores):self.name = nameself.scores = scoresdef __str__(self):return """姓名: {}, 各科成绩: {}""".format(self.name,self.scores,)def __add__(self, other: Student):name = "{}, {} 成绩合计".format(self.name, other.name)scores = [self.scores[i] + other.scores[i] for i in range(len(self.scores))]return Student(name, scores)def __sub__(self, other: Student):name = "{}, {} 成绩之差".format(self.name, other.name)scores = [self.scores[i] - other.scores[i] for i in range(len(self.scores))]return Student(name, scores)stu1 = Student("小明", [80, 90, 75])
stu2 = Student("小红", [85, 70, 95])
print(stu1)
print(stu2)
print(stu1 + stu2)
print(stu1 - stu2)# 运行结果
姓名: 小明, 各科成绩: [80, 90, 75]
姓名: 小红, 各科成绩: [85, 70, 95]
姓名: 小明, 小红 成绩合计, 各科成绩: [165, 160, 170]
姓名: 小明, 小红 成绩之差, 各科成绩: [-5, 20, -20]

其他的算术运算(比如,乘法,除法和求模等等)也有相应的魔法方法,仿照上面的示例实现即可。

6. 总结

Python魔法方法很多,本文只是列举了其中很少的一部分,
github上有一个示例python文件,列举了很多魔法方法,供参考:magicmethods.py


Python技术资源分享

小编是一名Python开发工程师,自己整理了一套 【最新的Python系统学习教程】,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。

保存图片微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

如果你是准备学习Python或者正在学习,下面这些你应该能用得上:

1、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

2、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

在这里插入图片描述

3、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

img

4、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

5、清华编程大佬出品《漫画看学Python》

用通俗易懂的漫画,来教你学习Python,让你更容易记住,并且不会枯燥乏味。

在这里插入图片描述

6、Python副业兼职与全职路线

在这里插入图片描述
这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

👉CSDN大礼包:《Python入门资料&实战源码&安装工具】免费领取安全链接,放心点击

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

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

相关文章

百兆集成RJ45连接器电路设计原理

华强盛电子导读&#xff1a;HR911105A-H1159A01A-GY百兆网口带变压器原理 百兆集成RJ45连接器电路设计原理涉及到网络通信和电子工程领域。RJ45连接器是一种常见的网络连接器&#xff0c;广泛应用于以太网和其他网络通信中。 以下是百兆集成RJ45连接器电路设计的基本原理&…

冠赢互娱基于 OpenKrusieGame 实现游戏云原生架构升级

作者&#xff1a;力铭 关于冠赢互娱 冠赢互娱是一家集手游、网游、VR 游戏等研发、发行于一体的游戏公司&#xff0c;旗下官方正版授权的传奇类手游——《仙境传奇》系列深受广大玩家们的喜爱。基于多年 MMORPG 类型游戏的自研与运营经验&#xff0c;冠赢互娱正式推出了 2D M…

【数据结构】快速排序(4种方式实现)

前言&#xff1a;前面我们学习了几种相对比较简单的排序&#xff0c;今天我们要一起学习的是快速排序&#xff0c;我们将通过四种方式来模拟实现快排。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:数据结构 &#x1f448; &#x1f4a…

OpenCV(Python)基础—9小时入门版

OpenCV(Python)基础—9小时入门版 # # Author : Mikigo # Time : 2021/12/1 # 一、一句话简介 OpenCV (Open Source Computer Vision Library) 是用 C 语言编写&#xff0c;提供 Python、Java 等语言 API的一个开源计算机视觉库。 二、安装 1、Debian 系使用 apt 安装 O…

Innosetup 调用c# dll 和 c# dll的函数导出

目标需求&#xff0c;基于现在安装包脚本。需要在用户安装和卸载成功时。进行数据记录,所以需要调用c#dll 主要涉及到的知识点 需要理解脚本的文件使用机制脚本的文件dll加载&#xff0c;和dll的调用c# dll的制作&#xff0c;和工具的使用 下面具体介绍 脚本的文件dll加载&…

OSPF的DR与BDR-新版(16)

目录 整体拓扑 操作步骤 1.基本配置 1.1 配置R1的IP 1.2 配置R2的IP 1.3 配置R3的IP 1.4 配置R4的IP 1.5 检测R1与R4连通性 1.6 检测R1与R2连通性 1.7 检测R1与R3连通性 2.搭建基本的OSPF网络 2.1 配置R1 OSPF 2.2 配置R2 OSPF 2.3 配置R3 OSPF 2.4 配置R4 OSPF…

八皇后问题(C语言)

了解题意 在一个8x8的棋盘上放置8个皇后&#xff0c;使得任何两个皇后都不能处于同一行、同一列或同一斜线上。问有多少种方法可以放置这8个皇后&#xff1f; 解决这个问题的目标是找到所有符合要求的皇后摆放方式&#xff0c;通常使用回溯算法来求解。回溯算法会尝试所有可能…

数据结构之树 --- 二叉树 < 堆 >

目录 1. 树是什么&#xff1f; 1.1 树的表示 2. 二叉树 2.1 二叉树的概念 2.2 特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储结构 2.4.1 顺序存储 2.4.2 链式存储 3. 二叉树顺序结构的实现 <堆> 3.1 二叉树的顺序结构 ​编辑 3.2 堆的概念及结构 ​编辑…

Appium+python自动化(八)- 初识琵琶女Appium(千呼万唤始出来,犹抱琵琶半遮面)- 下(超详解)

简介 通过上一篇宏哥给各位小伙伴们的引荐&#xff0c;大家移动对这位美女有了深刻的认识&#xff0c;而且她那高超的技艺和婀娜的身姿久久地浮现在你的脑海里&#xff0c;是不是这样呢&#xff1f;&#xff1f;&#xff1f;不要害羞直接告诉宏哥&#xff1a;是&#xff0c;就对…

C单片机数据类型与格式化

C语言数据类型 关键字位数表示范围stdint关键字ST关键字举例unsigned char80 ~ 255uint8_tu8u8 data 128char8-128 ~ 127int8_ts8s8 temperature 25unsigned short160 ~ 65535uint16_tu16u16 counter 5000short16-32768 ~ 32767int16_ts16s16 position 32767unsigned int3…

基于YOLOv5+Deepsort 的PCB缺陷检测及计数系统

背景&#xff1a; PCB&#xff08;Printed Circuit Board&#xff0c;印刷电路板&#xff09;是电子产品中至关重要的组成部分&#xff0c;它承载着电子元器件并提供电气连接。在PCB制造过程中&#xff0c;由于工艺、材料或设备等因素的影响&#xff0c;可能会引入各种缺陷&am…

电表通讯协议DLT645-2007编程

1、协议 电表有个电力行业推荐标准《DLT645-2007多功能电能表通信协议》&#xff0c;电表都支持&#xff0c;通过该协议读取数据&#xff0c;不同的电表不需要考虑编码格式、数据地址、高低位转换等复杂情况&#xff0c;统一采集。 不方便的地方在于这个协议定义得有点小复杂…

Strateg策略模式(组件协作)

策略模式&#xff08;组件协作&#xff09; 链接&#xff1a;策略模式实例代码 注解 目的 正常情况下&#xff0c;一个类/对象中会包含其所有可能会使用的内外方法&#xff0c;但是一般情况下&#xff0c;这些常使用的类都是由不同的父类继承、组合得来的&#xff0c;来实现…

跨境电商迎来综合竞争力比拼时代 五大趋势解读跨境2024

过去几年&#xff0c;跨境电商成为外贸出口增长的一大亮点&#xff0c;随着年底国务院办公厅《关于加快内外贸一体化发展的若干措施》的发布&#xff0c;跨境电商在促进经济发展、助力内外贸一体化发展方面的价值更加凸显。 这是跨境电商变化最快的时代&#xff0c;也是跨境电…

Getway介绍和使用

Getway 入门简介 网关搭建步骤&#xff1a; 创建项目&#xff0c;引入nacos服务发现和gateway依赖 配置application.yml&#xff0c;包括服务基本信息、nacos地址、路由 路由配置包括&#xff1a; 路由id&#xff1a;路由的唯一标示 路由目标&#xff08;uri&#xff09;…

常用环境部署(十二)——Redis搭建主从模式(一主一从)

一、主从服务器Redis安装 1、注意事项 主从服务器Redis尽量安装同一版本&#xff0c;避免兼容性造成的一些错误产生 2、Centos安装Redis 链接&#xff1a;​​​​​​常用环境部署(十)——MySQL主从同步数据搭建(一主一从)-CSDN博客 二、 主Redis配置 1、修改主Redis配置…

听说上海移动年终奖16个月!我承认我酸了!

* 你好&#xff0c;我是前端队长&#xff0c;在职场&#xff0c;玩副业&#xff0c;文末有福利! 今天&#xff0c;队长看到一篇帖子&#xff0c;有网友发帖说上海移动的年终奖发了16个月&#xff0c;我承认我酸了。 看到这里&#xff0c;我承认我也酸了。16个月是什么概念&…

【C/C++笔试练习】sort排序、STL容器、vector的特性、一级容器、迭代器失效、异常捕获、动态转换、统计每个月兔子的总数、字符串通配符

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;sort是不稳定排序&#xff08;2&#xff09;存放即有序的STL容器&#xff08;3&#xff09;连续储存的STL容器&#xff08;4&#xff09;vector的特性&#xff08;5&#xff09;一级容器&#xff08;6&#xff09;unorde…

PLC-IoT 网关开发札记(1):存档和分发 Android App

开篇记 PLC-IoT 网关是作者开发的产品&#xff0c;根据客户需求&#xff0c;立项开发手机 App&#xff0c;为用户提供一种方便、直观、友好的设备操控方式。网关运行的是嵌入式 Linux 操作系统&#xff0c;计划通过某一种通信协议&#xff08;例如 HTTP&#xff0c;MQTT或者 T…

大数定律中心极限定理

1.切比雪夫不等式 切比雪夫不等式可以对随机变量偏离期望值的概率做出估计&#xff0c;这是大数定律的推理基础。以下介绍一个对切比雪夫不等式的直观证明。 1.1 示性函数 对于随机事件A&#xff0c;我们引入一个示性函数 I A { 1 , A发生 0 , A不发生 I_A\begin{cases} 1&…