Python进阶:利用NotImplemented优化你的对象交互逻辑,让Python对象间的操作更加智能与灵活

news2024/9/27 15:20:59

推荐阅读:从混乱到清晰:用NotImplementedError重构你的Python代码,NotImplementedError如何助你打造更健壮的API

NotImplemented

在Python中,NotImplemented并不是一个异常类,而是一个特殊的值,用于在二元操作中表示某个操作对于该类型的对象是不适用的。当Python的内置二元操作(如加法+、乘法*、比较操作==等)在自定义类型上被调用,且这些操作在当前类型上没有定义时,可以返回NotImplemented。这样做允许Python解释器尝试调用另一个操作数的相应特殊方法,以实现操作符的重载或跨类型的操作。

NotImplemented的用途

  • 操作符重载:在Python中,你可以通过定义特殊方法(如__add__、mul、__eq__等)来实现操作符的重载。当你的类实现了这些特殊方法时,Python会在相应的操作符被调用时自动调用这些方法。然而,如果某个操作符在当前对象上无法执行,你可以返回NotImplemented,以指示Python尝试调用另一个操作数的相应方法。
  • 跨类型操作:在自定义类型之间进行操作时,如果某个操作在当前类型上未定义,但可能在另一个类型上有定义,返回NotImplemented可以允许Python自动尝试使用另一个操作数的实现。

NotImplemented与异常的区别

  • 类型不同:NotImplemented是一个特殊的值,而不是异常。它用于指示操作不适用,而不是指示错误或异常情况。
  • 用途不同:异常(如NotImplementedError)用于指示程序中的错误或异常情况,需要被捕获和处理。而NotImplemented则用于操作符重载和跨类型操作的上下文中,以指示某个操作在当前对象上无法执行。

注意事项

  • 当你在自定义类型的特殊方法中返回NotImplemented时,你应该意识到Python会尝试调用另一个操作数的相应方法。如果所有相关的方法都返回NotImplemented,Python将最终抛出一个TypeError。
  • NotImplemented不应该用于错误处理或异常情况。如果你的方法因为某种原因无法执行,并且你希望调用者知道这一点,你应该考虑抛出一个更具体的异常(如ValueError、TypeError或自定义异常)。

NotImplemented和NotImplementedError的区别

Python中的NotImplemented和NotImplementedError虽然听起来相似,但实际上它们在用途、类型和行为上都有着显著的区别。

类型与用途

NotImplemented:

  • 类型:NotImplemented是一个特殊的值,具体来说是types.NotImplementedType类型的唯一实例。它不是一个异常类,而是一个用于表示“未实现”或“不适用”的常量。
  • 用途:主要用于自定义二元方法(如__add__、__eq__等)中,当某个操作在当前对象上无法执行时,返回NotImplemented以指示Python解释器尝试调用另一个操作数的相应方法。这是实现操作符重载和跨类型操作的一种机制。

NotImplementedError:

  • 类型:NotImplementedError是一个内置的异常类,继承自Exception类。
  • 用途:用于表示一个方法或函数应该被实现,但实际上并没有被实现。它通常用于抽象基类(ABC)的抽象方法中,作为占位符,提醒子类必须覆盖(实现)这个方法。此外,它也可以在其他情况下用作异常抛出,以指示某个功能尚未实现。

行为差异

NotImplemented:

  • 当一个二元方法返回NotImplemented时,Python解释器会尝试调用另一个操作数的相应方法(如果存在的话),以尝试完成操作。如果所有相关的方法都返回NotImplemented,则最终会抛出一个TypeError。
  • 它不是通过raise语句抛出的,而是作为返回值使用的。

NotImplementedError:

  • 是一个异常,通过raise语句抛出。
  • 当抛出NotImplementedError时,它会被视为一个异常,需要被捕获和处理(除非在顶层代码中,它会被Python解释器捕获并打印堆栈跟踪)。
  • 它通常用于指示编程错误或未完成的功能,特别是在抽象编程和面向对象编程中。

代码案例

案例 1: 自定义数值类型的不对称加法

在这个案例中,我们定义一个自定义的数值类型MyNumber,它支持与自身的加法操作,但不直接支持与其他类型(如int或float)的加法。我们通过返回NotImplemented来表明当前对象不支持与另一个操作数的直接加法,这样Python会尝试调用另一个操作数的__radd__方法(如果它存在的话)。

class MyNumber:  
    def __init__(self, value):  
        self.value = value  
  
    def __add__(self, other):  
        # 检查other是否是MyNumber的实例  
        if isinstance(other, MyNumber):  
            # 如果是,执行加法并返回新的MyNumber实例  
            return MyNumber(self.value + other.value)  
        # 如果不是,返回NotImplemented,让Python尝试调用other的__radd__  
        # 但注意,我们在这里不实现__radd__,只是演示NotImplemented的用法  
        return NotImplemented  
  
    # 通常不需要显式实现__radd__,除非有特定的需求  
    # 如果要支持与非MyNumber类型的加法,可以在这里实现  
  
# 创建两个MyNumber实例  
a = MyNumber(5)  
b = MyNumber(3)  
  
# MyNumber与MyNumber相加  
print(a + b)  # 输出: <__main__.MyNumber object at 0x...>(具体输出会依Python解释器和运行时环境而异)  
# 但为了演示,我们可以添加一个__repr__方法来显示值  
class MyNumber:  
    # ...(前面的代码保持不变)  
    def __repr__(self):  
        return f"MyNumber({self.value})"  
  
# 重新创建实例并尝试相加  
a = MyNumber(5)  
b = MyNumber(3)  
print(a + b)  # 输出: MyNumber(8)  
  
# 尝试将MyNumber与int相加(这通常不会成功,因为没有实现__radd__或适当的类型转换)  
try:  
    print(a + 10)  # 这将抛出TypeError,因为没有合适的方法来处理这种加法  
except TypeError as e:  
    print(e)  # 输出可能是:"unsupported operand type(s) for +: 'MyNumber' and 'int'"

案例 2: 使用NotImplemented在特殊方法中表明不支持的操作

在这个案例中,我们定义一个简单的类SpecialObject,它只在某些情况下支持比较操作。我们将展示如何在不支持比较时返回NotImplemented。

class SpecialObject:  
    def __init__(self, value):  
        self.value = value  
  
    def __eq__(self, other):  
        # 仅当other也是SpecialObject且值相等时才认为相等  
        if isinstance(other, SpecialObject) and self.value == other.value:  
            return True  
        # 如果不满足条件,返回NotImplemented让Python尝试其他操作  
        return NotImplemented  
  
# 创建两个SpecialObject实例  
obj1 = SpecialObject(10)  
obj2 = SpecialObject(10)  
obj3 = SpecialObject(20)  
  
# 比较两个SpecialObject实例  
print(obj1 == obj2)  # 输出: True  
print(obj1 == obj3)  # 输出: False(实际上,由于__eq__返回NotImplemented,但这里我们故意让实例比较不相等的情况直接返回False作为示例)  
# 注意:实际上,如果__eq__返回NotImplemented,Python会尝试调用other的__eq__方法,  
# 但在这个例子中,我们没有这样做,只是简化了逻辑来演示概念。  
  
# 尝试将SpecialObject与int比较(这将导致TypeError,因为int没有处理来自SpecialObject的NotImplemented的逻辑)  
try:  
    print(obj1 == 10)  # 这将抛出TypeError,因为int的__eq__方法不知道如何处理来自SpecialObject的比较  
except TypeError as e:  
    print(e)  # 输出可能类似于:"unsupported operand type(s) for ==: 'SpecialObject' and 'int'"

推荐阅读

Python基础

Python全网最全基础课程笔记(一)——基础入门
Python全网最全基础课程笔记(二)——变量
Python全网最全基础课程笔记(三)——所有运算符+运算符优先级
Python全网最全基础课程笔记(四)——基本数据类型
Python全网最全基础课程笔记(五)——选择结构+Python新特性Match
Python全网最全基础课程笔记(六)——循环结构
Python全网最全基础课程笔记(七)——列表,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python全网最全基础课程笔记(八)——字典,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python全网最全基础课程笔记(九)——集合,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python全网最全基础课程笔记(十)——元组,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python全网最全基础课程笔记(十一)——字符串所有操作,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python全网最全基础课程笔记(十二)——函数,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!
Python全网最全基础课程笔记(十三)——作用域,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!

Flink入门到就业

2024年最新Flink教程,从基础到就业,大家一起学习–基础篇
2024年最新Flink教程,从基础到就业,大家一起学习–入门篇
2024年最新Flink教程,从基础到就业,大家一起学习–Flink集群部署
2024年最新Flink教程,从基础到就业,大家一起学习–flink部署和集群部署(从本地测试到公司生产环境如何部署项目源码)
2024年最新Flink教程,从基础到就业,大家一起学习–Flink运行架构底层源码详解+实战
2024年最新Flink教程,从基础到就业,大家一起学习–Flink DataStream API-第一篇+源码讲解

在这里插入图片描述

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

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

相关文章

linux桌面软件(wps)内嵌到其他窗口

程序测试环境是&#xff1a;slackware系统&#xff0c;属于linux系统&#xff0c;有桌面&#xff08;Xface Session&#xff09;。系统镜像是&#xff1a;slackware64-15.0-install-dvd.iso。qt、c代码实现。 程序功能&#xff1a;将已经打开的wps&#xff08;word、pdf等都可…

【优选算法】(第五篇)

目录 ⻓度最⼩的⼦数组&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⽆重复字符的最⻓⼦串&#xff08;medium&#xff09; 题目解析 讲解算法原理 编写代码 ⻓度最⼩的⼦数组&#xff08;medium&#xff09; 题目解析 1.题目链接&#xff1a;. - …

分割数组的最大值

题目链接 分割数组的最大值 题目描述 注意点 0 < nums[i] < 10^61 < nums.length < 10001 < k < min(50, nums.length) 解答思路 首先需要理解题意&#xff0c;需要将这个数组分成 k 个非空的连续子数组&#xff0c;找到划分组合中子数组和的最大值最小…

el-table+el-form实现表单校验和解决不垂直居中导致的问题

el-tableel-form实现表单校验 1.实现el-table的表单校验 关键点123 2.解决不垂直居中导致的问题 问题效果图 解决方案 .item-align-center {display: inline-flex; }

OJ在线评测系统 原生Java代码沙箱核心实现流程三 整理封装输出结果 拿到程序执行时间(stopwatch类) 和 运行内存

我们在之前的操作中已经拿到程序进行了编译和运行 接下来我们要将我们的结果输出 整理输出 // 4.收集整理输出结果 ExecuteCodeResponse executeCodeResponse new ExecuteCodeResponse(); ArrayList<String> outputList new ArrayList<>();for (ExecuteMessage…

Library介绍(一)

之前和大家介绍过cell delay是如何计算的。那么&#xff0c;本文将着重和大家介绍一些timing lib中的各个参数定义是什么意思。会分以下几个部分介绍&#xff1a;库属性描述、时序弧介绍、环境描述、单元描述。之前介绍的cell delay template就是单元描述中的一部分。本文主要介…

网络安全入门必备:这四点你做到了吗?

数据的鸿沟无疑是显而易见的&#xff0c;网络安全领域亟需熟练的专业人员。 组织在这方面投入巨大资金&#xff0c;但挑战依旧存在。 根据最新的研究&#xff0c;有64%的违规行为是导致机构过去一年收入损失及/或罚款的主要原因。 60%的组织在努力招聘网络安全人才&#xff…

【市场解读】新能源汽车换代问题

参考文献&#xff1a;百分点舆情中心《新能源汽车换代问题消费者情绪洞察报告》 行业背景 新能源汽车市场竞争加剧&#xff0c;车企不断推陈出新政府发布《汽车以旧换新补贴实施细则》&#xff0c;激励市场发展 *对汽车换代问题媒体关注度与网友讨论度高&#xff0c;正面声量…

电脑退域后系统黑屏

之前加入域时迁移了账号系统&#xff0c;导致退域后本地账号系统没了东西黑屏但能看到鼠标。也登不了域账号了一顿慌张&#xff08;操作如下&#xff09; 解决&#xff1a;又加回了域哈哈哈 重启电脑按F8进不去安全模式&#xff0c;找不到触发时间... winr打开运行&#xff0c;…

都说网络安全缺口那么大,但为何招聘数量却不多?总算明白了!

为啥网安领域缺口多达300多万人&#xff0c;但网安工程师也就是白帽黑客却很少&#xff0c;难道又是砖家在忽悠人&#xff1f; 原因主要为这三点: 首先是学校的原因&#xff0c;很多学校网络安全课程用的还都是十年前的老教材&#xff0c;教学脱离社会需求&#xff0c;实操技能…

【Python报错已解决】TypeError: expected Tensor as element 1 in argument 0, but got int

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

NHANES数据(复杂调查数据)亚组交互函数2.3版(P for interaction)发布---用于一键生成交互效应表

写在前面的话&#xff0c;本函数只支持NHANES数据(复杂调查数据)的逻辑回归和线性回归&#xff0c;其他类型均不支持&#xff0c;请注意甄别&#xff0c;电子产品&#xff0c;买错不能退换。 在SCI文章中&#xff0c;交互效应表格&#xff08;通常是表五&#xff09;能为文章锦…

多类别物体检测系统源码分享

多类别物体检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

“领航猿1号” 正式更名为 “AGI舰长”

亲爱的朋友们&#xff0c;很高兴的告诉大家&#xff1a; 我各个平台的账号昵称正式 由“领航猿1号” 更名为 “AGI舰长” 为什么更名&#xff1a; 为了更好的更专注的为大家提供关于“AI大模型全栈”的分享&#xff0c;特此以 AI 为关键元素更名账号名称&#xff0c;大家可以…

企业内网知识问答库小程序源码系统 收录好+排名高 带完整的安装代码包以及搭建部署教程

系统概述 企业内网知识问答库小程序源码系统是一款集知识收集、整理、检索与分享于一体的综合解决方案。它基于现代Web技术和小程序框架开发&#xff0c;旨在为企业内部员工提供一个便捷、高效的知识交流平台。该系统不仅支持文本、图片、视频等多种形式的内容输入&#xff0c…

国际版短剧系统开发,海外多语言切换短剧APP源码部署上架

一、背景与需求 1. 背景介绍 随着全球化进程的加速和移动互联网的普及&#xff0c;短剧作为一种新型娱乐形式在全球范围内迅速走红。海外短剧系统是针对这一市场需求而开发的&#xff0c;旨在为全球观众提供高质量的短剧内容&#xff0c;并通过多样化的平台和服务&#xff0c…

禁止吸烟监测系统 基于图像处理的吸烟检测系统 YOLOv7

吸烟是引发火灾的重要原因之一。烟头在未熄灭的情况下&#xff0c;其表面温度可达200℃-300℃&#xff0c;中心温度甚至能高达700℃-800℃。在易燃、易爆的生产环境中&#xff0c;如化工厂、加油站、仓库等&#xff0c;一个小小的烟头就可能引发灾难性的火灾&#xff0c;造成巨…

【前端样式】Sweetalert2简单用法

1、 先安装sweetalert2库&#xff1a; npm install sweetalert2 2、引用SweetAlert2 库&#xff1a; import Swal from sweetalert2 &#xff1b; 3、代码拷过去直接去测试&#xff0c;vue代码 <template><div><el-button style"color: #C03639" clic…

【计算机网络 - 基础问题】每日 3 题(二十八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

Kafka学习笔记(一)Linux环境基于Zookeeper搭建Kafka集群、Kafka的架构

文章目录 1 Kafka简介1.1 什么是Kafka1.2 Kafka的应用场景1.3 Kafka的优势 2 搭建Kafka集群2.1 搭建Zookeeper集群2.1.1 上传并解压安装包2.1.2 修改配置文件2.2.3 创建dataDir和myid文件2.2.4 分发到另外两个节点2.2.5 修改node-02节点、node-03节点的配置文件和myid文件2.2.6…