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

4.10.4 运算篇

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

4.10.4.1 add

add:obj1 + obj2

from icecream import ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __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 ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'Verctor({self.x}{self.y})'

    def __mul__(self, other):
        # v1 * v2
        if 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 ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f'Verctor({self.x}{self.y})'

    def __mul__(self, other):
        # v1 * v2
        if isinstance(other, int):
            return Vector(self.x * other, self.y * other)

    def __rmul__(self, other):
        # v1 * v2
        if 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 ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __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 ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __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 ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __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 ic


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __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.mfbz.cn/a/71161.html

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

相关文章

LeetCode 34题:在排序数组中查找元素的第一个和最后一个位置

目录 题目 思路 代码 C语言 Python 题目 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(…

腾讯出品Pag动画框架在Android端的使用-初级

Pag动画框架作为一个第三方框架&#xff0c;它的优缺点与Lottie是相似&#xff0c;此处不过多赘述。如果你们的项目中打算用了&#xff0c;肯定是经过了一定的调研的。Pag动画框架分几个版本&#xff0c;有免费的有收费的。我们目前用的社区免费版&#xff0c;只用来展示Pag动画…

大数据面试题:说下Spark中的Transform和Action,为什么Spark要把操作分为Transform和Action?

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 可回答&#xff1a;Spark常见的算子介绍一下 参考答案&#xff1a; 我们先来看下Spark算子的作用&#xff1a; 下图描述了Spark在运行转换中通过算…

uniapp的UI框架组件库——uView

在写uniapp项目时候&#xff0c;官方所推荐的样式库并不能满足日常的需求&#xff0c;也不可能自己去写相应的样式&#xff0c;费时又费力&#xff0c;所以我们一般会去使用第三方的组件库UI&#xff0c;就像vue里我们所熟悉的elementUI组件库一样的道理&#xff0c;在uniapp中…

(6)所有角色数据分析-6

http://t.csdn.cn/KrurEhttp://t.csdn.cn/KrurE &#xff08;5&#xff09;中的页面&#xff0c;倾向于向用户展示所有数据&#xff0c;但却没有对数据进行比较、分析&#xff0c;用户不能直观的感受到各种数据之间的关系与变化幅度&#xff0c;所以&#xff0c;下面将向用户提…

TCPDF生成PDF文件,含jpjraph生成雷达图

TCPDF生成PDF文件&#xff0c;含jpjraph生成雷达图 依赖自行安装 "tecnickcom/tcpdf": "^6.6","amenadiel/jpgraph": "4"雷达图生成 中文字体添加安装 没有封装&#xff0c;只作为测试案例展示 // 创建新的PDF文档$pdf new \TCPD…

中心极限定理例题

关于大数定律的两个题目。 例1 注意牢记公式&#xff1a; P { X } P { ∑ i 1 n x i − n μ n σ < x } ∫ − ∞ x e − x 2 2 d x 2 π P\{ X\} P \{\frac { \sum_{i1}^{n} x_i - n \mu}{\sqrt {n} \sigma} < x \} \frac {\int _{-\infty} ^{x} e ^{- \frac {x^…

18.3.0:Dynamic Web TWAIN Crack Web 文档扫描 SDK

Dynamic Web TWAIN用于快速部署 Web 应用程序的文档扫描 SDK&#xff0c;文档扫描SDK&#xff0c;&#xff0c;超过 5300 家公司信任 Dynamic Web TWAIN &#xff0c;因其稳健性和安全性而受到超过 5300 家公司的信赖&#xff0c;Dynamic Web TWAIN 是一款基于浏览器的文档扫描…

项目架构简介

目录 1 单体应用架构 2 垂直应用架构 3 分布式架构 3.1 RPC 3.2 SOA 4 微服务架构 本文介绍后台应用的各种架构,以及各架构的优缺点对比 1 单体应用架构 将所有的代码功能都写在一个项目中(例如:MVC结构,SSM框架),同时打包,同时部署 优点:便于管理,减少开发、维护、运维成…

Git全栈体系(六)

第十章 自建代码托管平台-GitLab 一、GitLab 简介 GitLab 是由 GitLabInc.开发&#xff0c;使用 MIT 许可证的基于网络的 Git 仓库管理工具&#xff0c;且具有 wiki 和 issue 跟踪功能。使用 Git 作为代码管理工具&#xff0c;并在此基础上搭建起来的 web 服务。GitLab 由乌克…

类与对象(加深)

目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 6.const成员 7.取地址及const取地址操作符重载 1.类的6个默认成员函数 如果…

01 - 工作区、暂存区、版本库、远程仓库 - 以一次连贯的提交操作为例

1. 工作区、暂存区、版本库、远程仓库 以一次连贯的提交操作为例。 1.1 工作区 Git的工作区也就是我们平时编辑代码的目录文件夹。 新建一个kongfu_person.txt文件&#xff0c;工作区的变化&#xff1a; 1.2 工作区 > 暂存区&#xff1a;git add 1.3 暂存区 > 版本库…

【踩坑】最新亲测能用!修复MacOS安装软件时提示“应该移到废纸篓”并且无法打开软件

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 目录 网上方法的尝试 方法一&#xff1a;xattr 方法二&#xff1a;UPX 真的能用的方法 GateKeeper_Helper.command的内容 网上方法的尝试 方法一&#xff1a;xattr 以前的Mac版本可以通过以下方式来解开限…

Gopeed-全平台开源高速下载器 支持(HTTP、BitTorrent、Magnet)协议

一、软件介绍 Gopeed&#xff08;全称 Go Speed&#xff09;&#xff0c;是一款由GolangFlutter开发的高速下载器&#xff0c;开源、轻量、原生&#xff0c;支持&#xff08;HTTP、BitTorrent、Magnet 等&#xff09;协议下载&#xff0c;并且支持全平台使用&#xff0c;底层使…

大华智慧园区综合管理平台文件上传漏洞复现(HW0day)

0x01 产品简介 “大华智慧园区综合管理平台”是一款综合管理平台&#xff0c;具备园区运营、资源调配和智能服务等功能。平台意在协助优化园区资源分配&#xff0c;满足多元化的管理需求&#xff0c;同时通过提供智能服务&#xff0c;增强使用体验。 0x02 漏洞概述 大华智慧园…

Android图形-合成与显示-SurfaceTestDemo

目录 引言&#xff1a; 主程序代码&#xff1a; 结果呈现&#xff1a; 小结&#xff1a; 引言&#xff1a; 通过一个最简单的测试程序直观Android系统的native层Surface的渲染显示过程。 主程序代码&#xff1a; #include <cutils/memory.h> #include <utils/L…

使用 PyTorch 逐步检测单个对象

一、说明 在对象检测任务中&#xff0c;我们希望找到图像中对象的位置。我们可以搜索一种类型的对象&#xff08;单对象检测&#xff0c;如本教程所示&#xff09;或多个对象&#xff08;多对象检测&#xff09;。通常&#xff0c;我们使用边界框定义对象的位置。有几种方法可以…

Ajax-概念、Http协议、Ajax请求及其常见问题

Ajax Ajax概念Ajax优缺点HTTP协议请求报文响应报文 Ajax案例准备工作express基本使用创建一个服务器 发送AJAX请求GET请求POST请求JSON响应 Ajax请求出现的问题IE缓存问题Ajax请求超时与网络异常处理Ajax手动取消请求Ajax重复发送请求问题 Ajax概念 AJAX 全称为Asynchronous J…

Python3 安装、环境变量配置、PyCharm新建Python项目

一、安装包下载 Pyhton官网下载>>最新稳定版的安装包&#xff1a; 找到合适的版本进行下载&#xff1a; 如果下载较慢&#xff0c;此处提供一个3.10.11的稳定版本的安装包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/16GnWjkGFuSfWfaI9UVX8qA?pwd4u5o 提取…

物联网的定义、原理、示例、未来

什么是物联网? 物联网 (IoT) 是指由嵌入传感器、软件和网络连接的物理设备、车辆、电器和其他物理对象组成的网络&#xff0c;允许它们收集和共享数据。这些设备(也称为“智能对象”)的范围可以从简单的“智能家居”设备(如智能恒温器)到可穿戴设备(如智能手表和支持RFID的服…
最新文章