当前位置: 首页 > news >正文

Python操作符的重载

目录

  • 1、操作符重载的基本概念
    • 1.1、常用的操作符重载方法
      • 1.1.1、算术操作符
      • 1.1.2、比较操作符
      • 1.1.3、比其他操作符
    • 1.2、例子
  • 2、应用场景
    • 2.1、增强代码的可读性
    • 2.2、 实现类的数学运算
    • 2.3、支持自定义的数据结构
    • 2.4、简化 API 设计
    • 2.5、实现链式操作和流式接口
  • 3、总结

Python 中的操作符重载(operator overloading)是一种让用户定义的对象可以使用标准操作符(如 +、-、* 等)进行运算的特性。通过操作符重载,我们可以让自定义的类实例在使用这些操作符时,表现出特定的行为。

1、操作符重载的基本概念

在 Python 中,操作符实际上是调用了某些特殊的方法。这些特殊方法以双下划线 __ 开头和结尾。例如,+ 操作符实际上是调用 __add__ 方法。

当你创建一个自定义类时,你可以定义这些特殊方法来实现操作符的重载。这样,操作符就可以在你的对象上进行自定义的操作。

1.1、常用的操作符重载方法

1.1.1、算术操作符

  • __add__(self, other):用于 + 操作符
  • __sub__(self, other):用于 - 操作符
  • __mul__(self, other):用于 * 操作符
  • __truediv__(self, other):用于 / 操作符
  • __floordiv__(self, other):用于 // 操作符
  • __mod__(self, other):用于 % 操作符
  • __pow__(self, other):用于 ** 操作符

1.1.2、比较操作符

  • __eq__(self, other):用于 == 操作符
  • __ne__(self, other):用于 != 操作符
  • __lt__(self, other):用于 < 操作符
  • __le__(self, other):用于 <= 操作符
  • __gt__(self, other):用于 > 操作符
  • __ge__(self, other):用于 >= 操作符

1.1.3、比其他操作符

  • __getitem__(self, key):用于 obj[key]
  • __setitem__(self, key, value):用于 obj[key] = value
  • __delitem__(self, key):用于 del obj[key]
  • __call__(self, *args, **kwargs):用于 obj(*args, **kwargs)
  • __str__(self):用于 str(obj) 和 print(obj)
  • __repr__(self):用于 repr(obj)

1.2、例子

class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __sub__(self, other):return Vector(self.x - other.x, self.y - other.y)def __mul__(self, scalar):return Vector(self.x * scalar, self.y * scalar)def __eq__(self, other):return self.x == other.x and self.y == other.ydef __str__(self):return f"Vector({self.x}, {self.y})"# 使用 Vector 类
v1 = Vector(2, 3)
v2 = Vector(4, 5)print(v1 + v2)  # 输出 Vector(6, 8)
print(v1 - v2)  # 输出 Vector(-2, -2)
print(v1 * 3)   # 输出 Vector(6, 9)
print(v1 == v2) # 输出 False

2、应用场景

2.1、增强代码的可读性

操作符重载可以让代码更具可读性。当你定义了一个自定义的类并且重载了操作符,你可以使用操作符的方式来进行类实例的操作,而不是调用方法。例如:

class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __repr__(self):return f"Vector({self.x}, {self.y})"v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2  # 使用重载的 "+" 操作符
print(v3)  # 输出 Vector(4, 6)

在这个例子中,+ 操作符被重载来实现 Vector 对象的相加,使得代码更清晰易懂。

2.2、 实现类的数学运算

如果你创建了一个表示数学对象(如向量、矩阵、复数等)的类,操作符重载可以让这些对象支持标准的数学运算。例如,重载 * 操作符来实现矩阵的乘法:

class Matrix:def __init__(self, data):self.data = datadef __mul__(self, other):result = [[0, 0], [0, 0]]for i in range(2):for j in range(2):result[i][j] = sum(self.data[i][k] * other.data[k][j] for k in range(2))return Matrix(result)def __repr__(self):return f"Matrix({self.data})"m1 = Matrix([[1, 2], [3, 4]])
m2 = Matrix([[5, 6], [7, 8]])
m3 = m1 * m2  # 使用重载的 "*" 操作符
print(m3)  # 输出 Matrix([[19, 22], [43, 50]])

2.3、支持自定义的数据结构

操作符重载可以让你为自定义的数据结构实现特定的行为。例如,如果你实现了一个自定义的容器类(如栈或队列),你可以重载操作符来支持标准的集合操作:

class Stack:def __init__(self):self.items = []def __add__(self, other):new_stack = Stack()new_stack.items = self.items + other.itemsreturn new_stackdef __repr__(self):return f"Stack({self.items})"s1 = Stack()
s1.items = [1, 2, 3]
s2 = Stack()
s2.items = [4, 5, 6]
s3 = s1 + s2  # 使用重载的 "+" 操作符
print(s3)  # 输出 Stack([1, 2, 3, 4, 5, 6])

2.4、简化 API 设计

操作符重载可以帮助简化 API 设计,使得用户与类的交互更加直观。例如,通过重载比较操作符 (==, <, >),你可以使类实例之间的比较变得自然:

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __lt__(self, other):return self.age < other.agedef __repr__(self):return f"Person(name={self.name}, age={self.age})"p1 = Person("Alice", 30)
p2 = Person("Bob", 25)
print(p1 < p2)  # 输出 False,因为 30 不小于 25

2.5、实现链式操作和流式接口

操作符重载使得链式操作成为可能。这种编程风格允许你将多个操作连在一起,使代码更加简洁和易于理解。例如,重载 | 操作符来支持管道操作。

class Step:def __or__(self, other):return ChainedOperation(self, other)class ChainedOperation:def __init__(self, first, second):self.first = firstself.second = seconddef invoke(self, data):intermediate_result = self.first.process(data)return self.second.parse(intermediate_result)class StepA(Step):def process(self, data):return data + " processed by StepA"class StepB(Step):def parse(self, data):return data + " and then by StepB"chain = StepA() | StepB()
result = chain.invoke("Initial data")
print(result)  # 输出: Initial data processed by StepA and then by StepB

3、总结

操作符重载在 Python 中可以提升代码的表达力和可读性,使得自定义对象能够以自然的方式参与运算。它允许开发者定义和控制自定义对象的行为,使其更加符合数学、逻辑或业务需求。然而,使用操作符重载时需要谨慎,以确保重载的行为符合操作符的直观意义,避免产生混淆。

相关文章:

Python操作符的重载

目录 1、操作符重载的基本概念1.1、常用的操作符重载方法1.1.1、算术操作符1.1.2、比较操作符1.1.3、比其他操作符 1.2、例子 2、应用场景2.1、增强代码的可读性2.2、 实现类的数学运算2.3、支持自定义的数据结构2.4、简化 API 设计2.5、实现链式操作和流式接口 3、总结 Python…...

redis面试(三)Hash数据结构

HASH 哈希&#xff0c;在redis底层实现的时候&#xff0c;数据的结构叫做dict 这个Dict就是一个用于维护key和value映射关系的数据结构&#xff0c;与很多语言中的Map类型相似。 本质上也是一个数组链表的形式存在&#xff0c;不同的点在于&#xff0c;每个dict中是可以存在…...

Java基础语法

注释 注释就是在程序指定位置添加的说明性信息 简单理解&#xff0c;就是对代码的一种解释 注释有三种&#xff1a; 单行注释 格式&#xff1a;//注释信息 多行注释 格式&#xff1a;/*注释信息*/ 文档注释 格式&#xff1a;/**注释信息*/ 注释的注意事项…...

Qt | QChart+QChartView+QLineSeries(折线图)+QBarSeries(柱状图)实战

点击上方"蓝字"关注我们 01、QLineSeries QLineSeries 是 Qt 中的一个类,用于在图表中表示一系列的数据点。它继承自 QAbstractSeries 类,提供了绘制折线图所需的基本功能。 常用的方法包括 append(x, y):向序列中添加一个新的数据点,其中 x 和 y 分别表示横坐…...

公布一批脸书爬虫(facebook)IP地址,真实采集数据

一、数据来源&#xff1a; 1、这批脸书爬虫&#xff08;facebook&#xff09;IP来源于尚贤达猎头公司网站采集数据&#xff1b; ​ 2、数据采集时间段&#xff1a;2023年10月-2024年7月&#xff1b; 3、判断标准&#xff1a;主要根据用户代理是否包含“facebook”和IP核实。…...

Package.Json 参数配置理解用途

"dev": "SET NODE_OPTIONS--openssl-legacy-provider & vue-cli-service serve --open" 这行命令首先设置环境变量NODE_OPTIONS&#xff0c;添加了--openssl-legacy-provider标志。这个标志用于解决某些情况下Node.js在Windows系统上使用OpenSSL时可能…...

k3:增加触发器,当外协单和报料单新增时,更新生产任务单的“说明”栏

外协单新增时 CREATE TRIGGER [dbo].[t_BOS257800018Entry2_update]ON [dbo].[t_BOS257800018Entry2]AFTER insert AS BEGINSET NOCOUNT ON; ------实现当外协时&#xff0c;生产任务单的说明有标识&#xff08;240731 BY WK&#xff09; declare fid_souce as int; declare…...

神奇海洋养鱼小程序游戏广告联盟流量主休闲小游戏源码

在海洋养鱼小程序中&#xff0c;饲料、任务系统、系统操作日志、签到、看广告、完成喂养、每日签到、系统公告、积分商城、界面设计、拼手气大转盘抽奖以及我的好友等功能共同构建了一个丰富而互动的游戏体验。以下是对这些功能的进一步扩展介绍&#xff1a; 饲料 任务奖励&a…...

分享几个适合普通人的AI副业变现思路

最近很多人问&#xff1a;看你做AI也做了有一两年了&#xff0c;也没见有什么产出啊&#xff1f;其实很多事情是长期主义&#xff0c;并不是一时半会儿马上就看到收益了。 正如董宇辉出名前也只是新东方默默无闻的一位老师&#xff0c;李佳琪曾经也只是一个化妆品销售。抱着长…...

如何使用CANoe自带的TCP/IP Stack验证TCP的零窗口探测机制

如果想利用CANoe自带的TCP/IP协议栈验证TCP的零窗口探测机制,就必须添加一个网络节点并配置独立的CANoe TCP/IP协议栈,作为验证对象。而与它进行TCP通信的对端也是一个网络节点,但不要配置TCP/IP协议栈,而是使用CAPL代码在底层组装TCP报文模拟TCP通信过程。这样可以尽量减少…...

二进制搭建 Kubernetes v1.20(中)

一、部署 CNI 网络组件 目录 一、部署 CNI 网络组件 1.flannel简介 1&#xff09;UDP模式 2&#xff09;VXLAN 模式 2.部署flannel ​编辑 3.Calico简介 1.flannel简介 K8S 中 Pod 网络通信&#xff1a;●Pod 内容器与容器之间的通信 在同一个 Pod 内的容器&#xff0…...

Scrapy 爬取旅游景点相关数据(七):利用指纹实现“不重复爬取”

本期学习&#xff1a; 利用网页指纹去重 众所周知&#xff0c;代理是要花钱的&#xff0c;那么在爬取&#xff08;测试&#xff09;巨量网页的时候&#xff0c;就不可能对已经爬取过的网站去重复的爬&#xff0c;这样会消耗大量的时间&#xff0c;更重要的是会消耗大量的IP (金…...

java的对象向上转型

对象向上转型&#xff0c;父类对象就可以调用子类重写父类的方法&#xff0c;这样当父类对象需要添加新的功能时&#xff0c;只需要添加一个子类&#xff0c;在子类中对父类的功能进行扩展&#xff0c;而不需要更改父类代码 向上转型&#xff0c;格式如下 父类类型 父类对象子…...

Navicat Premium 16破解

Navicat Premium 16破解教程 1安装Navicat Premium 16 通过百度网盘分享的文件&#xff1a;Navicat_Premium_16_chs-x64.zip 链接&#xff1a;https://pan.baidu.com/s/1ryRSJ2d9s6rXI09LEmLtpw?pwdz7wo 提取码&#xff1a;z7wo 一直下一步即可 2破解 选择刚才安装路径&am…...

【C/C++】C语言到C++的入门知识点(主要适用于C语言精通到Qt的C++开发入门)

【C/C】C语言到C的入门知识点&#xff08;主要适用于C语言精通到Qt的C开发入门&#xff09; 文章目录 C语言与C的不同C中写C语言代码C语言到C的知识点Qt开发中需要了解的C基础知识namespace输入输出字符串类型class类构造函数和析构函数&#xff08;解析函数&#xff09;类的继…...

docker 建木 发版 (详细教程)

先创建git仓库 Git勤勉 两种方式上传-CSDN博客 把项目送上去 进入建木 可以接着这个来 dockerfile部署镜像 -&#xff1e;push仓库 -&#xff1e;虚拟机安装建木 -&#xff1e;自动部署化 (详细步骤)-CSDN博客 创建分组项目 开始操作 git 上钩子 前面链接里有这个教…...

什么样的人适合学习网络安全?

一、引言 在当今数字化的时代&#xff0c;网络安全已经成为了一个至关重要的领域。随着网络攻击的日益频繁和复杂&#xff0c;对于网络安全专业人才的需求也在不断增长。然而&#xff0c;并不是每个人都适合学习网络安全。那么&#xff0c;究竟什么样的人适合投身于这个充满挑…...

大厂linux面试题攻略四之Linux网络服务(二)

五、Linux网络服务-Apache优化 1.请写出工作中常见的Apache优化策略 Apache服务器优化是提升网站响应速度和稳定性的重要手段。在工作中&#xff0c;常见的Apache优化策略包括以下几个方面&#xff1a; 1. 启用压缩技术 Gzip压缩&#xff1a;使用Gzip压缩技术可以减少服务器…...

MySQL和PostgreSQL group by后 Concatenate 拼接所有的字符串

MySQL&#xff1a; GROUP_CONCAT(DISTINCT t2.T_CODES ORDER BY t2.T_CODES ASC) AS t_str, PostgreSQL 8.4 array_to_string(array_agg(t2.T_CODES), , ) AS t_str, PostgreSQL 9 string_agg(t2.T_CODES), , )...

Python爬虫技术 第24节 数据清洗和预处理(二)

在Python爬虫项目中&#xff0c;数据清洗和预处理是非常关键的步骤。这部分工作通常涉及到字符串操作、缺失值处理和数据格式转换等方面。下面我将详细讲解这些方面的内容&#xff0c;并提供具体的代码示例。 1. 字符串操作 字符串操作在数据清洗过程中非常重要&#xff0c;因…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

跨平台商品数据接口的标准化与规范化发展路径:淘宝京东拼多多的最新实践

在电商行业蓬勃发展的当下&#xff0c;多平台运营已成为众多商家的必然选择。然而&#xff0c;不同电商平台在商品数据接口方面存在差异&#xff0c;导致商家在跨平台运营时面临诸多挑战&#xff0c;如数据对接困难、运营效率低下、用户体验不一致等。跨平台商品数据接口的标准…...