详解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中isalnum()方法的使用
May 18 Python
python类和继承用法实例
Jul 07 Python
Python中subprocess的简单使用示例
Jul 28 Python
Python实现统计文本文件字数的方法
May 05 Python
centos 安装Python3 及对应的pip教程详解
Jun 28 Python
Python Pandas 箱线图的实现
Jul 23 Python
Apache部署Django项目图文详解
Jul 30 Python
Python函数的定义方式与函数参数问题实例分析
Dec 26 Python
Macbook安装Python最新版本、GUI开发环境、图像处理、视频处理环境详解
Feb 17 Python
python数据库开发之MongoDB安装及Python3操作MongoDB数据库详细方法与实例
Mar 18 Python
Python常用GUI框架原理解析汇总
Dec 07 Python
python关于集合的知识案例详解
May 30 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中的时间处理
2006/10/09 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
详解WordPress中调用评论模板和循环输出评论的PHP函数
2016/01/05 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
接收键盘指令的脚本
2006/06/26 Javascript
将json当数据库一样操作的javascript lib
2013/10/28 Javascript
js中判断用户输入的值是否为空的简单实例
2013/12/23 Javascript
jQuery中fadeOut()方法用法实例
2014/12/24 Javascript
浅析JavaScript访问对象属性和方法及区别
2015/11/16 Javascript
Jquery easyui开启行编辑模式增删改操作
2016/01/14 Javascript
基于jQuery实现以手风琴方式展开和折叠导航菜单
2016/01/28 Javascript
给easyui的datebox控件添加清空按钮的实现方法
2016/11/09 Javascript
通过命令行创建vue项目的方法
2017/07/20 Javascript
JavaScript运行原理分析
2018/02/09 Javascript
详解js的视频和音频采集
2018/08/09 Javascript
vue 的点击事件获取当前点击的元素方法
2018/09/15 Javascript
如何对react hooks进行单元测试的方法
2019/08/14 Javascript
vue项目配置使用flow类型检查的步骤
2020/03/18 Javascript
Javascript实现简易天数计算器
2020/05/18 Javascript
[02:07]TI9显影之尘系列 - Vici Gaming
2019/08/20 DOTA
基于进程内通讯的python聊天室实现方法
2015/06/28 Python
详解 Python中LEGB和闭包及装饰器
2017/08/03 Python
flask + pymysql操作Mysql数据库的实例
2017/11/13 Python
python快速建立超简单的web服务器的实现方法
2018/02/17 Python
python的concat等多种用法详解
2018/11/28 Python
如何使用Python标准库进行性能测试
2019/06/25 Python
PyCharm+Pipenv虚拟环境开发和依赖管理的教程详解
2020/04/16 Python
python中round函数如何使用
2020/06/19 Python
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
如何估计一张表的大小(假设该表中有1万条数据)
2016/03/27 面试题
中职毕业生自我鉴定
2014/09/13 职场文书
学校副校长四风对照检查材料整改措施
2014/09/25 职场文书
2014年幼儿园个人工作总结
2014/11/10 职场文书
2015年万圣节活动总结
2015/03/24 职场文书
茶花女读书笔记
2015/06/29 职场文书
CSS使用伪类控制边框长度的方法
2022/01/18 HTML / CSS