详解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实现rest请求api示例
Apr 22 Python
Python解析最简单的验证码
Jan 07 Python
简单谈谈Python中的几种常见的数据类型
Feb 10 Python
Django数据库操作的实例(增删改查)
Sep 04 Python
ubuntu环境下python虚拟环境的安装过程
Jan 07 Python
python实现反转部分单向链表
Sep 27 Python
python根据txt文本批量创建文件夹
Dec 08 Python
python打开使用的方法
Sep 30 Python
python3 mmh3安装及使用方法
Oct 09 Python
python飞机大战pygame碰撞检测实现方法分析
Dec 17 Python
浅谈Python 参数与变量
Jun 20 Python
关于Python使用turtle库画任意图的问题
Apr 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
很实用的一个完整email发送程序
2006/10/09 PHP
简单说说PHP优化那些事(经验分享)
2014/11/27 PHP
解析WordPress中的post_class与get_post_class函数
2016/01/04 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
2020/03/23 PHP
php实现记事本案例
2020/10/20 PHP
[全兼容哦]--实用、简洁、炫酷的页面转入效果loing
2007/05/07 Javascript
javascript 函数使用说明
2010/04/07 Javascript
取得窗口大小 兼容所有浏览器的js代码
2011/08/09 Javascript
jQuery在html有效在jsp无效的原因及解决方法
2013/08/02 Javascript
使用typeof判断function是否存在于上下文
2014/08/14 Javascript
Javascript发送AJAX请求实例代码
2016/08/21 Javascript
Bootstrap路径导航与分页学习使用
2017/02/08 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
理解 JavaScript EventEmitter
2018/03/29 Javascript
使用mpvue搭建一个初始小程序及项目配置方法
2018/12/03 Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
2019/03/29 Javascript
详细讲解如何创建, 发布自己的 Vue UI 组件库
2019/05/29 Javascript
JavaScript数组排序的六种常见算法总结
2020/08/18 Javascript
解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题
2020/09/02 Javascript
JS canvas实现画板和签字板功能
2021/02/23 Javascript
python实现的重启关机程序实例
2014/08/21 Python
Python实现可获取网易页面所有文本信息的网易网络爬虫功能示例
2018/01/15 Python
对python_discover方法遍历所有执行的用例详解
2019/02/13 Python
pygame编写音乐播放器的实现代码示例
2019/11/19 Python
Pytorch 多块GPU的使用详解
2019/12/31 Python
Python3中小括号()、中括号[]、花括号{}的区别详解
2020/11/15 Python
荷兰多品牌网上鞋店:Stoute Schoenen
2017/08/24 全球购物
快时尚眼镜品牌,全国连锁眼镜店:LOHO眼镜生活
2018/10/08 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
市场营销个人求职信范文
2014/02/02 职场文书
幼儿园毕业园长感言
2014/02/24 职场文书
经营理念口号
2014/06/21 职场文书
2014年党员学习“三严三实”思想汇报
2014/09/15 职场文书
导游词之南京中山陵
2019/11/27 职场文书
Go timer如何调度
2021/06/09 Golang
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python