详解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操作xml文件示例
Apr 07 Python
使用Python脚本对Linux服务器进行监控的教程
Apr 02 Python
详解Python中的相对导入和绝对导入
Jan 06 Python
python编写朴素贝叶斯用于文本分类
Dec 21 Python
python2.7读取文件夹下所有文件名称及内容的方法
Feb 24 Python
NLTK 3.2.4 环境搭建教程
Sep 19 Python
python实现给scatter设置颜色渐变条colorbar的方法
Dec 13 Python
Python常用爬虫代码总结方便查询
Feb 25 Python
python 利用pywifi模块实现连接网络破解wifi密码实时监控网络
Sep 16 Python
python安装scipy的步骤解析
Sep 28 Python
Django app配置多个数据库代码实例
Dec 17 Python
python中print格式化输出的问题
Apr 16 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数据采集的详解
2013/06/02 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
php使用正则表达式获取字符串中的URL
2016/12/29 PHP
php获取给定日期相差天数的方法分析
2017/02/20 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
laravel框架上传图片实现实时预览功能
2019/10/14 PHP
JSON JQUERY模板实现说明
2010/07/03 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
jquery改变tr背景色的示例代码
2013/12/28 Javascript
Javascript基础教程之数组 array
2015/01/18 Javascript
javascript实现瀑布流自适应遇到的问题及解决方案
2015/01/28 Javascript
百度UEditor编辑器如何关闭抓取远程图片功能
2015/03/03 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
2015/09/15 Javascript
jquery实现仿新浪微博带动画效果弹出层代码(可关闭、可拖动)
2015/10/12 Javascript
jQuery实现悬浮在右上角的网页客服效果代码
2015/10/24 Javascript
用js实现博客打赏功能
2016/10/24 Javascript
详解如何在Vue2中实现组件props双向绑定
2017/03/29 Javascript
微信小程序分享海报生成的实现方法
2018/12/10 Javascript
利用jsonp解决js读取本地json跨域的问题
2018/12/11 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
2020/11/11 Javascript
Python实现的ini文件操作类分享
2014/11/20 Python
Python类方法__init__和__del__构造、析构过程分析
2015/03/06 Python
使用pycharm生成代码模板的实例
2018/05/23 Python
完美解决Python matplotlib绘图时汉字显示不正常的问题
2019/01/29 Python
Python如何爬取51cto数据并存入MySQL
2020/08/25 Python
一款纯css3实现的圆形旋转分享按钮旋转角度可自己调整
2014/09/02 HTML / CSS
html5的websockets全双工通信详解学习示例
2014/02/26 HTML / CSS
使用SVG实现提示框功能的示例代码
2020/06/05 HTML / CSS
具有防紫外线功能的高性能钓鱼服装:Hook&Tackle
2018/08/16 全球购物
Piercing Pagoda官网:耳环、戒指、项链、手链等
2020/09/28 全球购物
求职简历中个人的自我评价
2013/12/01 职场文书
技校毕业生自荐信范文
2014/03/07 职场文书
工程材料采购方案
2014/05/18 职场文书
整改报告格式
2014/11/06 职场文书
小学班级口号大全
2015/12/25 职场文书