详解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生成pdf文件的方法
Aug 04 Python
python uuid模块使用实例
Apr 08 Python
速记Python布尔值
Nov 09 Python
python scipy求解非线性方程的方法(fsolve/root)
Nov 12 Python
pyshp创建shp点文件的方法
Dec 31 Python
Django中信号signals的简单使用方法
Jul 04 Python
用python建立两个Y轴的XY曲线图方法
Jul 08 Python
python 提取文件指定列的方法示例
Aug 07 Python
解析Python3中的Import
Oct 13 Python
python无序链表删除重复项的方法
Jan 17 Python
python图形开发GUI库pyqt5的基本使用方法详解
Feb 14 Python
python 爬取吉首大学网站成绩单
Jun 02 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
Access数据库导入Mysql的方法之一
2006/10/09 PHP
php使用strtotime和date函数判断日期是否有效代码分享
2013/12/25 PHP
crontab无法执行php的解决方法
2016/01/25 PHP
利用PHP生成静态html页面的原理
2016/09/30 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
php实现数组中出现次数超过一半的数字的统计方法
2018/10/14 PHP
php7性能提升的原因详解
2019/10/13 PHP
JAVASCRIPT keycode总结
2009/02/04 Javascript
js几秒以后倒计时跳转示例
2013/12/26 Javascript
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2014/08/16 Javascript
在JavaScript中使用JSON数据
2016/02/15 Javascript
JavaScript根据CSS的Media Queries来判断浏览设备的方法
2016/05/10 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
vue组件间通信解析
2017/03/01 Javascript
js判断用户是输入的地址请求的路径(实例讲解)
2017/07/18 Javascript
前端主流框架vue学习笔记第二篇
2017/07/26 Javascript
React中上传图片到七牛的示例代码
2017/10/10 Javascript
javacript replace 正则取字符串中的值并替换【推荐】
2018/09/13 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
vuejs+element UI table表格中实现禁用部分复选框的方法
2019/09/20 Javascript
Angular封装表单控件及思想总结
2019/12/11 Javascript
python使用pyhook监控键盘并实现切换歌曲的功能
2014/07/18 Python
快速入手Python字符编码
2016/08/03 Python
python如何去除字符串中不想要的字符
2020/07/05 Python
Python3视频转字符动画的实例代码
2019/08/29 Python
python golang中grpc 使用示例代码详解
2020/06/03 Python
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
html5 Canvas绘制线条 closePath()实例代码
2012/05/10 HTML / CSS
是什么让J2EE适合用来开发多层的分布式的应用
2015/01/16 面试题
如果一个类实现了多个接口但是这些接口有相同的方法名将会怎样
2013/06/16 面试题
汽车检测与维修专业求职信
2013/10/30 职场文书
大学生简单自荐信
2013/11/10 职场文书
2014年党员公开承诺书范文
2014/03/28 职场文书
2015年班组工作总结
2015/04/20 职场文书
nginx proxy_cache 缓存配置详解
2021/03/31 Servers
Python超详细分步解析随机漫步
2022/03/17 Python