详解Python中内置的NotImplemented类型的用法


Posted in Python onMarch 31, 2015

它是什么?
 

>>> type(NotImplemented)
<type 'NotImplementedType'>

NotImplemented 是Python在内置命名空间中的六个常数之一。其他有False、True、None、Ellipsis 和 __debug__。和 Ellipsis很像,NotImplemented 能被重新赋值(覆盖)。对它赋值,甚至改变属性名称, 不会产生 SyntaxError。所以它不是一个真正的“真”常数。当然,我们应该永远不改变它。 但是为了完整性:
 

>>> None = 'hello'
...
SyntaxError: can't assign to keyword
>>> NotImplemented
NotImplemented
>>> NotImplemented = 'do not'
>>> NotImplemented
'do not'

它有什么用?什么时候用?

NotImplemented 是个特殊值,它能被二元特殊方法返回(比如__eq__() 、 __lt__()  、 __add__() 、 __rsub__() 等),表明某个类型没有像其他类型那样实现这些操作。同样,它或许会被原地处理(in place)的二元特殊方法返回(比如__imul__()、__iand__()等)。还有,它的实际值为True:
 

>>> bool(NotImplemented)
True

你也许会问自己,“但我认为当这个操作没有实现时,我应该产生个NotImpementedError”。我们会看些例子,关于为什么当实现二元特殊方法时不是这么回事儿。

让我们看看NotImplemented常数的用法,通过__eq__()对于两个非常基本(且没用)的类 A 和 B 的编码。[对于这个简单的例子,为了避免干扰,不会实现__ne__() ,但是总的说来,每次实现__eq__() 时, __ne__()也应该被实现,除非,有个足够充分的理由去不实现它。]
 

# example.py
 
class A(object):
  def __init__(self, value):
    self.value = value
 
  def __eq__(self, other):
    if isinstance(other, A):
      print('Comparing an A with an A')
      return other.value == self.value
    if isinstance(other, B):
      print('Comparing an A with a B')
      return other.value == self.value
    print('Could not compare A with the other class')
    return NotImplemented
 
class B(object):
  def __init__(self, value):
    self.value = value
 
  def __eq__(self, other):
    if isinstance(other, B):
      print('Comparing a B with another B')
      return other.value == self.value
    print('Could not compare B with the other class')
    return NotImplemented

现在,在解释器中:
 

>>> from example import A, B
>>> a1 = A(1)
>>> b1 = B(1)

我们现在可以实验下对于 __eq__() 不同的调用,看看发生了什么。作为提醒,在Python中,a == b会调用a.__eq__(b):
 

>>> a1 == a1
Comparing an A with an A
True

正如所望,a1等于a1(自己),使用类A中的__eq__()来进行这个比较的。比较b1和它自己也会产生类似结果:
 

>>> b1 == b1
Comparing a B with another B
True

现在,那要是我们比较a1和b1呢?由于在A的__eq__()会检查other是不是B的一个实例,我们想要a1.__eq__(b1)去处理这个比较并返回True:
 

>>> a1 == b1
Comparing an A with a B
True

就是这样。现在,如果我们比较b1和a1(即调用b1.__eq__(a1)),我们会想要返回NotImplemented。这是因为B的__eq__()只和其他B的实例进行比较。来看看发生了什么:
 

>>> b1 == a1
Could not compare B against the other class
Comparing an A with a B
True

聪明!b1.__eq__(a1)方法返回NotImplemented,这样会导致调用A中的__eq__()方法。而且由于在A中的__eq__()定义了A和B之间的比较,所以就得到了正确的结果(True)。

这就是返回了NotImplemented的所做的。NotImplemented告诉运行时,应该让其他对象来完成某个操作。在表达b1 == a1中,b1.__eq__(a1)返回了NotImplemented,这说明Python试着用a1.__eq__(b1)。由于a1足够可以返回True,因此这个表达可以成功。如果A中的__eq__()也返回NotImplemented,那么运行时会退化到使用内置的比较行为,即比较对象的标识符(在CPython中,是对象在内存中的地址)。

注意:如果在调用b1.__eq__(a1)时抛出NotImpementedError,而不进行处理,就会中断代码的执行。而NotImplemented无法抛出,仅仅是用来进一步测试是否有其他方法可供调用。

Python 相关文章推荐
python实现的简单窗口倒计时界面实例
May 05 Python
Python批量按比例缩小图片脚本分享
May 21 Python
Python统计日志中每个IP出现次数的方法
Jul 06 Python
python字典值排序并取出前n个key值的方法
Oct 17 Python
用python一行代码得到数组中某个元素的个数方法
Jan 28 Python
python实现两张图片的像素融合
Feb 23 Python
python pygame实现五子棋小游戏
Oct 26 Python
如何用Python破解wifi密码过程详解
Jul 12 Python
Pycharm创建项目时如何自动添加头部信息
Nov 14 Python
Python基础之字符串格式化详解
Apr 21 Python
windows安装python超详细图文教程
May 21 Python
Python趣味挑战之给幼儿园弟弟生成1000道算术题
May 28 Python
python计算N天之后日期的方法
Mar 31 #Python
使用Python3中的gettext模块翻译Python源码以支持多语言
Mar 31 #Python
python根据出生日期获得年龄的方法
Mar 31 #Python
用Python进行一些简单的自然语言处理的教程
Mar 31 #Python
用Python制作在地图上模拟瘟疫扩散的Gif图
Mar 31 #Python
以一段代码为实例快速入门Python2.7
Mar 31 #Python
11个并不被常用但对开发非常有帮助的Python库
Mar 31 #Python
You might like
PHP动态输出JavaScript代码实例
2015/02/12 PHP
事件绑定之小测试  onclick &amp;&amp; addEventListener
2011/07/31 Javascript
JavaScript异步编程:异步数据收集的具体方法
2013/08/19 Javascript
xmlhttp缓存清除的2种解决方法
2013/12/13 Javascript
Javascript 按位取反运算符 (~)
2014/02/04 Javascript
js检测浏览器版本、核心、是否移动端示例
2014/04/24 Javascript
jQuery实现倒计时按钮功能代码分享
2014/09/03 Javascript
jquery中EasyUI实现同步树
2015/03/01 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
微信小程序实现顶部导航特效
2019/01/28 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
javascript随机变色实例代码
2019/10/15 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
python下MySQLdb用法实例分析
2015/06/08 Python
使用实现XlsxWriter创建Excel文件并编辑
2018/05/04 Python
opencv与numpy的图像基本操作
2019/03/08 Python
Python静态类型检查新工具之pyright 使用指南
2019/04/26 Python
python pycharm最新版本激活码(永久有效)附python安装教程
2020/09/18 Python
Python3.7黑帽编程之病毒篇(基础篇)
2020/02/04 Python
windows10在visual studio2019下配置使用openCV4.3.0
2020/07/14 Python
推荐值得学习的12款python-web开发框架
2020/08/10 Python
python多线程和多进程关系详解
2020/12/14 Python
CSS3实现的文本3D效果附图
2014/09/03 HTML / CSS
文案策划求职信
2014/04/14 职场文书
国际商贸专业自荐信
2014/06/09 职场文书
节约每一滴水演讲稿
2014/09/09 职场文书
退休党员个人对照检查材料思想汇报
2014/09/29 职场文书
先进单位事迹材料
2014/12/25 职场文书
民事上诉状范文
2015/05/22 职场文书
乡镇团委工作总结2015
2015/05/26 职场文书
Python 实现Mac 屏幕截图详解
2021/10/05 Python
Python Django获取URL中的数据详解
2021/11/01 Python
大脑的记忆过程在做数据压缩,不同图形也有共同的记忆格式
2022/04/29 数码科技