详解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的session中使用User对象的方法
Jul 23 Python
Python算术运算符实例详解
May 31 Python
Python实现两款计算器功能示例
Dec 19 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
Dec 25 Python
对python打乱数据集中X,y标签对的方法详解
Dec 14 Python
在python下读取并展示raw格式的图片实例
Jan 24 Python
python实现顺时针打印矩阵
Mar 02 Python
Python 面向对象之类class和对象基本用法示例
Feb 02 Python
Python安装OpenCV的示例代码
Mar 05 Python
浅谈matplotlib.pyplot与axes的关系
Mar 06 Python
Python 实现自动登录+点击+滑动验证功能
Jun 10 Python
Python包和模块的分发详细介绍
Jun 19 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代码的53条建议
2008/03/27 PHP
利用php+mysql来做一个功能强大的在线计算器
2010/10/12 PHP
php判断输入不超过mysql的varchar字段的长度范围
2011/06/24 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
PHP实现的二分查找算法实例分析
2017/12/19 PHP
js判断浏览器类型的方法
2013/08/07 Javascript
用JavaScript计算在UTF-8下存储字符串占用字节数
2013/08/08 Javascript
Jquery实现的角色左右选择特效
2014/05/21 Javascript
jQuery中ajax的post()方法用法实例
2014/12/26 Javascript
JavaScript获得url所有参数键值表的方法
2015/03/21 Javascript
js+html5绘制图片到canvas的方法
2015/06/05 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
2015/08/28 Javascript
JavaScript程序设计之JS调试
2015/12/09 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
2016/12/26 Javascript
vue中echarts3.0自适应的方法
2018/02/26 Javascript
jQuery实现的手动拖动控制进度条效果示例【测试可用】
2018/04/18 jQuery
在vue中v-bind使用三目运算符绑定class的实例
2018/09/29 Javascript
使用webpack打包后的vue项目如何正确运行(express)
2018/10/26 Javascript
VUE实现密码验证与提示功能
2019/10/18 Javascript
[01:04]DOTA2上海特锦赛现场采访 FreeAgain遭众解说围攻
2016/03/25 DOTA
[00:37]2016完美“圣”典风云人物:AMS宣传片
2016/12/06 DOTA
[54:09]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
python使用matplotlib模块绘制多条折线图、散点图
2020/04/26 Python
Django的用户模块与权限系统的示例代码
2019/07/24 Python
Python如何操作office实现自动化及win32com.client的运用
2020/04/01 Python
在python中使用pyspark读写Hive数据操作
2020/06/06 Python
Python关于拓扑排序知识点讲解
2021/01/04 Python
CSS3实现全景图特效示例代码
2018/03/26 HTML / CSS
医学检验专业大学生求职信
2013/11/18 职场文书
一岗双责责任书
2014/04/15 职场文书
微笑面对生活演讲稿
2014/05/13 职场文书
2015年入党积极分子培养考察意见
2015/08/12 职场文书
青年干部培训班学习心得体会
2016/01/06 职场文书
红灯733-1型14管5波段半导体收音机
2021/04/22 无线电
教你利用Selenium+python自动化来解决pip使用异常
2021/05/20 Python