详解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 相关文章推荐
Django 生成登陆验证码代码分享
Dec 12 Python
使用python编写简单的小程序编译成exe跑在win10上
Jan 15 Python
学习Python3 Dlib19.7进行人脸面部识别
Jan 24 Python
Python列表解析配合if else的方法
Jun 23 Python
windows下pycharm安装、创建文件、配置默认模板
Jul 31 Python
python使用matplotlib绘制热图
Nov 07 Python
找Python安装目录,设置环境路径以及在命令行运行python脚本实例
Mar 09 Python
使用openCV去除文字中乱入的线条实例
Jun 02 Python
python中altair可视化库实例用法
Jan 26 Python
python 遍历磁盘目录的三种方法
Apr 02 Python
分享python函数常见关键字
Apr 26 Python
Python+Pillow+Pytesseract实现验证码识别
May 11 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
叶罗丽:为什么大家对颜冰这对CP非常关心,却对金茉两人十分冷漠
2020/03/17 国漫
php若干单维数组遍历方法的比较
2011/09/20 PHP
PHP采集类Snoopy抓取图片实例
2014/06/19 PHP
Thinkphp+smarty+uploadify实现无刷新上传
2015/07/30 PHP
PHP中如何防止外部恶意提交调用ajax接口
2016/04/11 PHP
PHP函数rtrim()使用中的怪异现象分析
2017/02/24 PHP
jQuery 中关于CSS操作部分使用说明
2007/06/10 Javascript
JavaScript使用slice函数获取数组部分元素的方法
2015/04/06 Javascript
jQuery插件pagination实现无刷新分页
2016/05/21 Javascript
javascript函数的四种调用模式
2017/01/08 Javascript
你可能不知道的前端算法之文字避让(inMap)
2018/01/12 Javascript
React学习笔记之高阶组件应用
2018/06/02 Javascript
js前端面试之同步与异步问题详解
2019/04/03 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
2019/06/24 Javascript
vue.js 解决v-model让select默认选中不生效的问题
2020/07/28 Javascript
vue路由的配置和页面切换详解
2020/09/09 Javascript
[00:09]DOTA2全国高校联赛 精彩活动引爆全场
2018/05/30 DOTA
详细探究Python中的字典容器
2015/04/14 Python
Python使用metaclass实现Singleton模式的方法
2015/05/05 Python
python 中split 和 strip的实例详解
2017/07/12 Python
Python实现矩阵相乘的三种方法小结
2018/07/26 Python
Python3.5集合及其常见运算实例详解
2019/05/01 Python
python程序变成软件的实操方法
2019/06/24 Python
Pytorch之parameters的使用
2019/12/31 Python
Python加密模块的hashlib,hmac模块使用解析
2020/01/02 Python
python简单实现最大似然估计&amp;scipy库的使用详解
2020/04/15 Python
Python3实现建造者模式的示例代码
2020/06/28 Python
Python+Appium实现自动化清理微信僵尸好友的方法
2021/02/04 Python
html5使用canvas画一条线
2014/12/15 HTML / CSS
英国办公用品商店:Office Outlet
2018/04/04 全球购物
定义一结构体变量,用其表示点坐标,并输入两点坐标,求两点之间的距离
2015/08/17 面试题
毕业寄语大全
2014/04/09 职场文书
今冬明春火灾防控工作方案
2014/05/29 职场文书
个人委托书范本汇总
2014/10/01 职场文书
2014年教研员工作总结
2014/12/23 职场文书
win10拖拽文件时崩溃怎么解决?win10文件不能拖拽问题解决方法
2022/08/14 数码科技