[Python进阶] 定制类:运算篇

4.10.4 运算篇

Python的类型系统是鸭子类型,也就是不检查某个具体的对象是什么类型,而是检查这个对象有没有相应的功能。在Python中有大量的魔术方法,我们可以通过魔术方法的方式为对象添加相应的功能。
下面介绍Python中和运算相关的魔术方法。这些魔术方法是对两个对象在进行符号运算时对相应的运算符号进行重载,从而实现相应的效果。
在本篇所讲的运算相关的魔术方法中,参数other并不一定要和self一致。
很多时候我们用魔术方法,只是借用了这个符号,并不一定要符号该符号原来的定义。比如:我们可以将<<左移符号重载成C++中的cout。

4.10.4.1 add

add:obj1 + obj2

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Vertor({self.x}{self.y})'def __add__(self, other):return Vector(self.x + other.x, self.y + other.y)v1 = Vector(0, 1)
v2 = Vector(2, 3)
print(v1 + v2)

Vertor(2,4)

4.10.4.2 sub

sub:obj1 – obj2

4.10.4.3 mulmatmulpow

mul:obj1 * obj2
matmul:obj1 @ obj2
pow:obj1 ** obj2、pow(obj1, obj2, mod=None)  (obj1 ** obj2) % mod

4.10.4.4 truedivfloordivmoddivmod

truediv:obj1 / obj2
floordiv:obj1 // obj2
mod:obj1 % obj2
divmod:divmod(obj1,obj2)

4.10.4.5 lshiftrshift

lshift:obj1 << obj2
rshift:obj1 >> obj2

4.10.4.6 andxoror

and:obj1 & obj2
xor:obj1 ^ obj2
or:obj1 | obj2

4.10.4.7 运算符的r版本

如下代码所示,当我们自定义乘法,判断相乘的对象是int类型时,则将x,y同时和int相乘并返回。但是,如果是int类型数据和我们自定义的Vector类型相乘时,则会报错,因为是Python内置的int类型是不知道要如何和我们自定义的Vector类型相乘的。

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Verctor({self.x}{self.y})'def __mul__(self, other):# v1 * v2if isinstance(other, int):return Vector(self.x * other, self.y * other)v1 = Vector(2, 3)
ic(v1 * 2)  # 本质:v1.__mul__(2)
ic(2 * v1)

ic| v1 * 2: Verctor(4,6)
Traceback (most recent call last):
File “E:\BaiduSyncdisk\FrbPythonFiles\t2.py”, line 20, in
ic(2 * v1)
TypeError: unsupported operand type(s) for *: ‘int’ and ‘Vector’

解决办法是定义一个__rmul__魔法方法,如下:

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Verctor({self.x}{self.y})'def __mul__(self, other):# v1 * v2if isinstance(other, int):return Vector(self.x * other, self.y * other)def __rmul__(self, other):# v1 * v2if isinstance(other, int):return Vector(self.x * other, self.y * other)v1 = Vector(2, 3)
ic(v1 * 2)
ic(2 * v1)

ic| v1 * 2: Verctor(4,6)
ic| 2 * v1: Verctor(4,6)

这样一来,如果操作符左侧的这个数据结构没有定义这个操作应该怎么完成的话,Python就会尝试去找操作符右侧这个对象的操作符的r版本魔法方法。这样就可以正常完成int * Verctor的操作了。
这里,之前列出的所有和数的计算有关的魔法方法都有其r版本。

4.10.4.8 运算符的i版本

i版本运算符魔法方法最后是修改self并返回。其实对应的符号就是操作符=。比如:v1 += v2就会调用:v1.iadd(v2)。

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Vertor({self.x}{self.y})'def __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __iadd__(self, other):return Vector(self.x * other.x, self.y * other.y)v1 = Vector(0, 1)
v2 = Vector(2, 3)
ic(v1 + v2)
v1 += v2
ic(v1)

ic| v1 + v2: Vertor(2,4)
ic| v1: Vertor(0,3)

我们看到,v += v2 时调用了__iadd__魔术方法。返回结果:Vertor(0,3)。但其实,我们不创建这个__iadd__魔术方法也可以。

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Vertor({self.x}{self.y})'def __add__(self, other):return Vector(self.x + other.x, self.y + other.y)v1 = Vector(0, 1)
v2 = Vector(2, 3)
ic(v1 + v2)
v1 += v2
ic(v1)

ic| v1 + v2: Vertor(2,4)
ic| v1: Vertor(2,4)

在本节前面提到的魔术方法中,所有使用符号触发的都有其对应的i版本。也就是:+=、-=、*=…

4.10.4.9 negpos

这2个魔术方法对应的是在数据结构之前添加一个-+符号。
neg:-obj
pos:+obj

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Vertor({self.x}{self.y})'def __neg__(self):return Vector(-self.x, -self.y)def __pos__(self):return Vector(self.x, self.y)v1 = Vector(-2, 3)
ic(-v1)
ic(+v1)

ic| -v1: Vertor(2,-3)
ic| +v1: Vertor(-2,3)

4.10.4.10 absinvert

abs:abs(obj)
invert:~obj # 位运算中的反转

4.10.4.11 complexintfloat

complex:complex(obj)
int:int(obj)
float:float(obj)
这3个魔术方法规定返回的结果必须是其对应的数据结构。

4.10.4.12 index

index:代表当你把这个数据结构当成index使用的时候等价于什么。
如果我们定义了这个__index__,而没有定义__ complex__、int、__float__方法的话,那么complex、int、float都会默认使用这个__index__魔法方法。

from icecream import icclass Vector:def __init__(self, x, y):self.x = xself.y = ydef __repr__(self):return f'Vertor({self.x}{self.y})'def __index__(self):return int(self.x)v1 = Vector(2, 3)
lst = list('Python')
ic(lst[v1])  # [v1]返回2,相当于:lst[int(self.x)]

ic| lst[v1]: ‘t’

4.10.4.13 roundtruncfloorceil

round:round(obj) # 四舍五入
trunc:math.trunc(obj) # 无条件舍弃小数
floor:math.floor(obj) # 向负无穷取整
ceil:math.ceil(obj) # 向正无穷取整

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

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

相关文章

从零开始学python(十六)爬虫集群部署

前言 今天讲述Python框架源码专题最后一个部分&#xff0c;爬虫集群部署&#xff0c;前面更新了十五个从零开始学python的系列文章&#xff0c;分别是&#xff1a; 1.编程语法必修篇 2.网络编程篇 3.多线程/多进程/协程篇 4.MySQL数据库篇 5.Redis数据库篇 6.MongoDB数据库篇 …

运维监控学习笔记2

硬件监控&#xff1a; 1&#xff09;使用IPMI 2&#xff09;机房巡检 路由器和交换机&#xff1a; 使用SNMP&#xff08;简单网络管理协议&#xff09;进行监控。 Linux 安装snmp&#xff1a; yum install -y net-snmp net-snmp-utils 说明&#xff1a;net-snmp是安装在snm…

到 2030 年API 攻击预计将激增近 1000%

导读云原生应用程序编程接口管理公司 Kong 联合外部经济学家的最新研究预计&#xff0c;截至 2030 年 API 攻击将激增 996%&#xff0c;意味着与 API 相关的网络威胁的频率和强度都显着升级。 这项研究由 Kong 分析师和布朗大学副教授 Christopher Whaley 博士合作进行&#x…

StarGANv2: Diverse Image Synthesis for Multiple Domains论文解读及实现(一)

StarGAN v2: Diverse Image Synthesis for Multiple Domainsp github:https://github.com/clovaai/stargan-v2 1 模型架构 模型主要架构由四部分组成 ①Generator、②Mapping network、③Style encoder、④Discriminator Generator&#xff1a;G网络 生成模型G将输入图片x转换…

数字普惠金融、数字创新与经济增长—基于省级面板数据的实证考察(2011-2021年)

参照陈啸&#xff08;2023&#xff09;的做法&#xff0c;本对来自经济问题《数字普惠金融、数字创新与经济增长——基于省级面板数据的实证考察》一文中的基准回归部分进行复刻。数字普惠金融、数字创新已经成为驱动经济高质量发展的关键。利用省级面板数据&#xff0c;构建固…

【软件测试】UI自动化框架,数据驱动 vs 关键字驱动怎么选

一、UI自动化测试用例剖析 让我们先从分析一端自动化测试案例的代码开始我们的旅程。以下是我之前写的一个自动化测试的小Demo。这个Demo基于Selenium与Java。 自动化测试小Demo 它要测试的东西其实是要看一下百度搜索能不能返回兴业银行的官网。我们分析一下这段代码都包含些…

达蒙DM数据库使用经验

DM表/字段注释 注&#xff1a;dm数据库无法在建表的同时为字段名添加注释 //为表添加注释 comment on table 库名.表名 is 表注释; //为表字段添加注释 comment on column 库名.表名.列名 is 列注释;DM查询错误&#xff1a;无效的表或视图 1&#xff0c;确认表一定存在 2&am…

清除pip安装库时的缓存

目录 1、命令清除缓存 2、路径手动清除 在使用pip安装Python库时&#xff0c;如果之前已经下载过该库&#xff0c;pip会默认使用缓存来安装库&#xff0c;而不是重新从网络上下载。缓存文件通常存储在用户目录下的缓存文件夹中&#xff0c;具体位置因操作系统和Python版本而异…

elementui 的 dialog 常用逻辑总结

菜鸟最近写后台管理系统&#xff0c;发现不管是弹窗、还是编辑、查看、添加等功能&#xff0c;真的代码都差不多&#xff0c;但是每次都要重新写里面的关闭逻辑等&#xff0c;菜鸟就感觉不如搞一个模版&#xff0c;后面只关注于逻辑&#xff0c;其他都直接来这里复制了&#xf…

项目管理师基础之项目管理计划和项目文件

项目管理过程中&#xff0c;会使用并产生两大类文件&#xff1a;项目管理计划和项目文件。内容一般如下&#xff1a; 整个项目生命周期需要收集、分析和转化大量的数据。从各个过程收集项目数据&#xff0c;并在项目团队内共享。在各个过程中所收集的数据经过结合相关背景的分…

MySQL中同比和环比语句如何写?

营收表如下&#xff08;表名&#xff1a;a&#xff09;如下图&#xff1a; 营收表 year month money 2021 1 1000 2021 2 1200 2022 1 1300 2022 2 1500 需要算出2022年营收同比与环比&#xff1a; 同比&#xff1a;和去年同月相比&#xff08;1300-1000/1000*100%&#xff0…

Python +numpy数组膨胀(填充)方法总结

本文主要介绍数组的各种填充方法&#xff0c;包括数组按照原值复制扩大并填充&#xff0c;数组的扩大填充&#xff0c;数组边缘填充等。 1.数组的复制膨胀 形如二维数组: [[1 2] [3 4]] 膨胀为&#xff1a; [[1 1 1 2 2 2] [1 1 1 2 2 2] [1 1 1 2 2 2] [3 3 3 4 4 4]…

简单易用且高效的跨平台开发工具:Xojo 2023 for Mac

Xojo for Mac是Mac平台上一个跨平台的针对桌面、Web、移动和Raspberry Pi的快速应用程序开发软件。与其他多平台开发工具相比&#xff0c;Xojo for Mac为开发人员提供了显着的生产率提高。 Xojo for Mac具有拖放功能&#xff0c;使您能够快速创建用户界面设计&#xff0c;然后…

Android保存网页的方法

首先要使用js交互就需要懂原理&#xff1a; 感谢大佬&#xff1a;js中document节点获取页面元素的六种方式 1.querySelector()方法 描述&#xff1a;本方法用于根据给定的选择器选中页面元素 如果有多个元素满足条件&#xff0c;则返回第一个满足条件的元素节点 语法&#xff…

GRPC-连接池-GPT

gRPC Dart 管理优化 User grpc for dart 如何统一管理多个Client的创建和销毁&#xff0c;给我一个最优解 ChatGPT 对于在Dart中使用gRPC创建和销毁多个Client的统一管理&#xff0c;您可以使用一个单例模式的管理类来实现最优解。 首先&#xff0c;创建一个管理类&#xff0c…

EPPlus 读取和生成Excel

在项目中添加了EPPlus库的引用&#xff0c;你可以通过NuGet包管理器或手动将EPPlus库添加到项目中。同时&#xff0c;需要注意的是EPPlus库支持的是xlsx格式的Excel文件。 读取 使用EPPlus读取本地Excel文件的示例代码如下&#xff1a; using OfficeOpenXml;public void Rea…

算法随笔:图论问题之割点割边

割点 定义 割点的定义&#xff1a;如果一个点被删除之后会导致整个图不再是一个连通图&#xff0c;那么这个顶点就是这个图的割点。举例&#xff1a; 上图中的点2就是一个割点&#xff0c;如果它被删除&#xff0c;则整个图被分为两个连通分量&#xff0c;不再是一个连通图。…

【交换排序】冒泡排序 与 快速排序

交换排序基本思想&#xff1a; 所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置&#xff0c;交换排序的特点是&#xff1a;将键值较大的记录向序列的尾部移动&#xff0c;键值较小的记录向序列的前部移动。 目录 1.冒泡排序 2.快…

OptaPlanner笔记5

2.4 与spring boot集成 2.4.4 添加依赖 <dependency><groupId>org.optaplanner</groupId><artifactId>optaplanner-spring-boot-starter</artifactId> </dependency>2.4.8 创建求解器服务 import org.optaplanner.core.api.solver.Solv…

Django笔记之数据库函数之日期函数

日期函数主要介绍两个大类&#xff0c;Extract() 和 Trunc() Extract() 函数作用是提取日期&#xff0c;比如我们可以提取一个日期字段的年份&#xff0c;月份&#xff0c;日等数据 Trunc() 的作用则是截取&#xff0c;比如 2022-06-18 12:12:12&#xff0c;我们可以根据需求…