详解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判断windows系统是32位还是64位的方法
May 11 Python
Python实现截屏的函数
Jul 26 Python
Python的网络编程库Gevent的安装及使用技巧
Jun 24 Python
Python sqlite3事务处理方法实例分析
Jun 19 Python
python处理数据,存进hive表的方法
Jul 04 Python
python+Splinter实现12306抢票功能
Sep 25 Python
配置 Pycharm 默认 Test runner 的图文教程
Nov 30 Python
pandas的相关系数与协方差实例
Dec 27 Python
python中threading开启关闭线程操作
May 02 Python
浅析Python 条件控制语句
Jul 15 Python
Python+OpenCV图像处理—— 色彩空间转换
Oct 22 Python
Python数据分析入门之数据读取与存储
May 13 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中运用jQuery的Ajax跨域调用实现代码
2012/02/21 PHP
PHP图像处理类库MagickWand用法实例分析
2015/05/21 PHP
PHP常用文件操作函数和简单实例分析
2016/06/03 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
PHP whois查询类定义与用法示例
2019/04/03 PHP
JS判定是否原生方法
2013/07/22 Javascript
AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
2015/01/02 Javascript
javascript实现跨域的方法汇总
2015/06/25 Javascript
js实现TAB切换对应不同颜色的代码
2015/08/31 Javascript
php利用curl获取远程图片实现方法
2015/10/26 Javascript
JS模拟实现方法重载示例
2016/08/03 Javascript
微信小程序购物商城系统开发系列-工具篇的介绍
2016/11/21 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
2017/03/08 Javascript
微信小程序 input表单与redio及下拉列表的使用实例
2017/09/20 Javascript
arcgis for js栅格图层叠加(Raster Layer)问题
2017/11/22 Javascript
Vue2.0用户权限控制解决方案
2017/11/29 Javascript
vue中实现左右联动的效果
2018/06/22 Javascript
[45:16]完美世界DOTA2联赛PWL S3 Magma vs Phoenix 第一场 12.12
2020/12/16 DOTA
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
2015/04/25 Python
浅析Git版本控制器使用
2017/12/10 Python
浅析PHP与Python进行数据交互
2018/05/15 Python
python读取一个目录下所有txt里面的内容方法
2018/06/23 Python
解决pycharm工程启动卡住没反应的问题
2019/01/19 Python
python判断一个对象是否可迭代的例子
2019/07/22 Python
opencv 形态学变换(开运算,闭运算,梯度运算)
2020/07/07 Python
Python word文本自动化操作实现方法解析
2020/11/05 Python
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
Laura Geller官网:美国彩妆品牌
2018/12/29 全球购物
有影响力的人、名人和艺术家的官方商品:Represent
2019/11/26 全球购物
如何写一封打动人心的求职信
2014/02/17 职场文书
物控部经理职务说明书
2014/02/25 职场文书
2015年度电厂个人工作总结
2015/05/13 职场文书
tensorflow学习笔记之tfrecord文件的生成与读取
2021/03/31 Python
Python中文纠错的简单实现
2021/07/07 Python
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
2021/08/02 MySQL
MySQL常见优化方案汇总
2022/01/18 MySQL