详解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 相关文章推荐
python3使用urllib示例取googletranslate(谷歌翻译)
Jan 23 Python
用Python和MD5实现网站挂马检测程序
Mar 13 Python
详解Python中with语句的用法
Apr 15 Python
python版本的仿windows计划任务工具
Apr 30 Python
python获取代理IP的实例分享
May 07 Python
python用户评论标签匹配的解决方法
May 31 Python
Flask框架Jinjia模板常用语法总结
Jul 19 Python
matplotlib实现热成像图colorbar和极坐标图的方法
Dec 13 Python
python将excel转换为csv的代码方法总结
Jul 03 Python
4行Python代码生成图像验证码(2种)
Apr 07 Python
python实现发送邮件
Mar 02 Python
关于Python OS模块常用文件/目录函数详解
Jul 01 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实现获取图片颜色值的方法
2014/07/11 PHP
PHP函数eval()介绍和使用示例
2014/08/20 PHP
PHP的Socket通信之UDP通信实例
2015/07/02 PHP
Javascript Function对象扩展之延时执行函数
2010/07/06 Javascript
JS Date函数整理方便使用
2013/10/23 Javascript
jquery获取及设置outerhtml的方法
2015/03/09 Javascript
javascript基于DOM实现权限选择实例分析
2015/05/14 Javascript
js制作网站首页图片轮播特效代码
2016/08/30 Javascript
js仿小米官网图片轮播特效
2016/09/29 Javascript
jQuery编写网页版2048小游戏
2017/01/06 Javascript
Angular通过指令动态添加组件问题
2018/07/09 Javascript
Element Carousel 走马灯的具体实现
2020/07/26 Javascript
使用Python构建Hopfield网络的教程
2015/04/14 Python
一个基于flask的web应用诞生 flask和mysql相连(4)
2017/04/11 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
2020/06/23 Python
Python基于递归和非递归算法求两个数最大公约数、最小公倍数示例
2018/05/21 Python
python统计字母、空格、数字等字符个数的实例
2018/06/29 Python
python性能测量工具cProfile使用解析
2019/09/26 Python
python批量将excel内容进行翻译写入功能
2019/10/10 Python
Python Websocket服务端通信的使用示例
2020/02/25 Python
python使用PIL剪切和拼接图片
2020/03/23 Python
在keras中对单一输入图像进行预测并返回预测结果操作
2020/07/09 Python
Python基于gevent实现文件字符串查找器
2020/08/11 Python
Club Monaco加拿大官网:设计师男女服装
2019/09/29 全球购物
什么是serialVersionUID
2016/03/04 面试题
亿企通软件测试面试题
2012/04/10 面试题
师范毕业生求职自荐信
2013/09/25 职场文书
党的群众路线教育实践活动心得体会
2014/03/03 职场文书
信息工作经验交流材料
2014/05/28 职场文书
质量月口号
2014/06/20 职场文书
学生会竞选演讲稿纪检部
2014/08/25 职场文书
2015年个人招商工作总结
2015/04/25 职场文书
2016年教师师德师风心得体会
2016/01/12 职场文书
《蓝鲸的眼睛》读后感5篇
2020/01/15 职场文书
JavaScript中isPrototypeOf函数
2021/11/07 Javascript
mysql幻读详解实例以及解决办法
2022/06/16 MySQL