详解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获得图片base64编码示例
Jan 16 Python
python妹子图简单爬虫实例
Jul 07 Python
python查看微信好友是否删除自己
Dec 19 Python
Python实现将Excel转换为json的方法示例
Aug 05 Python
Python序列化基础知识(json/pickle)
Oct 19 Python
快速解决安装python没有scripts文件夹的问题
Apr 03 Python
django中ORM模型常用的字段的使用方法
Mar 05 Python
使用 Python ssh 远程登陆服务器的最佳方案
Mar 06 Python
使用jupyter Nodebook查看函数或方法的参数以及使用情况
Apr 14 Python
Python 多线程共享变量的实现示例
Apr 17 Python
Python 爬取淘宝商品信息栏目的实现
Feb 06 Python
python爬取豆瓣电影排行榜(requests)的示例代码
Feb 18 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做推送服务端实现ios消息推送
2013/07/01 PHP
php命名空间学习详解
2014/02/27 PHP
jquerydom对象的事件隐藏显示和对象数组示例
2013/12/10 Javascript
Javascript原型链和原型的一个误区
2014/10/22 Javascript
jQuery实现瀑布流的取巧做法分享
2015/01/12 Javascript
js代码验证手机号码和电话号码是否合法
2015/07/30 Javascript
jQuery拖动布局其结果保存到数据库
2015/10/09 Javascript
jquery实现简单的遮罩层
2016/01/08 Javascript
动态加载js、css的实例代码
2016/05/26 Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
2016/10/11 Javascript
用jQuery实现可输入多选下拉组合框实例代码
2017/01/18 Javascript
JavaScript数组去重的多种方法(四种)
2017/09/19 Javascript
关于ES6箭头函数中的this问题
2018/02/27 Javascript
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
vue实现放大镜效果
2020/09/17 Javascript
[01:51]历届DOTA2国际邀请赛举办地回顾 TI9落地上海
2018/08/26 DOTA
[46:49]完美世界DOTA2联赛PWL S3 access vs Rebirth 第二场 12.19
2020/12/24 DOTA
Python2.x利用commands模块执行Linux shell命令
2016/03/11 Python
关于初始种子自动选取的区域生长实例(python+opencv)
2020/01/16 Python
Django实现内容缓存实例方法
2020/06/30 Python
Python安装Bs4的多种方法
2020/11/28 Python
html5摇一摇代码优化包括DeviceMotionEvent等等
2014/09/01 HTML / CSS
美国眼镜网站:EyeBuyDirect
2017/04/13 全球购物
Kathmandu美国网站:新西兰户外运动品牌
2019/03/23 全球购物
英国最大的滑板品牌选择:Route One
2019/09/22 全球购物
为什么group by 和order by会使查询变慢
2014/05/16 面试题
.NET面试题:什么是反射
2016/09/30 面试题
大学专科生推荐信范文
2013/11/23 职场文书
关于旷工的检讨书
2014/02/02 职场文书
通信工程求职信
2014/07/16 职场文书
科级干部群众路线教育实践活动个人对照检查材料
2014/09/19 职场文书
单位租房协议书范本
2014/12/04 职场文书
企业党建工作总结2015
2015/05/26 职场文书
MySQL定时备份数据库(全库备份)的实现
2021/09/25 MySQL
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技
Java的Object类的九种方法
2022/04/13 Java/Android