源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

详解Python中内置的NotImplemented类型的用法

  • 时间:2020-05-10 21:07 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:详解Python中内置的NotImplemented类型的用法
[b]它是什么? [/b] 
>>> type(NotImplemented)
<type 'NotImplementedType'>
[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url] 是Python在内置命名空间中的六个常数之一。其他有[url=https://docs.python.org/3.4/library/constants.html#False]False[/url]、[url=https://docs.python.org/3.4/library/constants.html#True)]True[/url]、[url=https://docs.python.org/3.4/library/constants.html#False)]None[/url]、Ellipsis 和 [url=https://docs.python.org/3.4/library/constants.html#__debug__.]__debug__。[/url]和 Ellipsis很像,[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url] 能被重新赋值(覆盖)。对它赋值,甚至改变属性名称, 不会产生 SyntaxError。所以它不是一个真正的“真”常数。当然,我们应该永远不改变它。 但是为了完整性:  
>>> None = 'hello'
...
SyntaxError: can't assign to keyword
>>> NotImplemented
NotImplemented
>>> NotImplemented = 'do not'
>>> NotImplemented
'do not'
[b]它有什么用?什么时候用?[/b] [url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented [/url]是个特殊值,它能被二元特殊方法返回(比如[url=https://docs.python.org/3.4/reference/datamodel.html#object.__eq__]__eq__()[/url] 、 [url=https://docs.python.org/3.4/reference/datamodel.html#object.__lt__]__lt__() [/url] 、 [url=https://docs.python.org/3.4/reference/datamodel.html#object.__add__]__add__() [/url]、 __rsub__() 等),表明某个类型没有像其他类型那样实现这些操作。同样,它或许会被原地处理(in place)的二元特殊方法返回(比如__imul__()、__iand__()等)。还有,它的实际值为True:  
>>> bool(NotImplemented)
True
你也许会问自己,“但我认为当这个操作没有实现时,我应该产生个[url=https://docs.python.org/3.4/library/exceptions.html#NotImplementedError]NotImpementedError[/url]”。我们会看些例子,关于为什么当实现二元特殊方法时不是这么回事儿。 让我们看看[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url]常数的用法,通过[url=https://docs.python.org/3.4/reference/datamodel.html#object.__eq__]__eq__()[/url]对于两个非常基本(且没用)的类 A 和 B 的编码。[对于这个简单的例子,为了避免干扰,不会实现[url=https://docs.python.org/3.4/reference/datamodel.html#object.__ne__]__ne__() [/url],但是总的说来,每次实现[url=https://docs.python.org/3.4/reference/datamodel.html#object.__eq__]__eq__() [/url]时, [url=https://docs.python.org/3.4/reference/datamodel.html#object.__ne__]__ne__()[/url]也应该被实现,除非,有个足够充分的理由去不实现它。]  
# 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)),我们会想要返回[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url]。这是因为B的__eq__()只和其他B的实例进行比较。来看看发生了什么:  
>>> b1 == a1
Could not compare B against the other class
Comparing an A with a B
True
聪明!b1.__eq__(a1)方法返回[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url],这样会导致调用A中的__eq__()方法。而且由于在A中的__eq__()定义了A和B之间的比较,所以就得到了正确的结果(True)。 这就是返回了[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url]的所做的。[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url]告诉运行时,应该让其他对象来完成某个操作。在表达b1 == a1中,b1.__eq__(a1)返回了[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url],这说明Python试着用a1.__eq__(b1)。由于a1足够可以返回True,因此这个表达可以成功。如果A中的__eq__()也返回[url=https://docs.python.org/3.4/library/constants.html#NotImplemented]NotImplemented[/url],那么运行时会退化到使用内置的比较行为,即比较对象的标识符(在CPython中,是对象在内存中的地址)。 注意:如果在调用b1.__eq__(a1)时抛出NotImpementedError,而不进行处理,就会中断代码的执行。而NotImplemented无法抛出,仅仅是用来进一步测试是否有其他方法可供调用。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部