社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

[译]简析 Python 的 `NotImplemented`

一个普普通通简简单单平平凡凡的神 • 7 年前 • 381 次点击  
导读:本文讨论 Python 的 NotImplemented它是什么,它意味着什么,什么时候应该使用。

是什么

>>> type(NotImplemented)
<type 'NotImplementedType'>

NotImplemented是 Python 内置命名空间中的六个常量之一。其他还有 False, True, None, Ellipsis__debug__。类似于 EllipsisNotImplemented可以重新赋值。 赋值给它,即使作为属性名称,也不会引发SyntaxError异常,所以它不是真正的“真实(real/true)”的常量。当然,我们永远都不应该重新赋值它。 但是,为了完整:

>>> None = 'hello'
...
SyntaxError: can't assign to keyword
>>> NotImplemented
NotImplemented
>>> NotImplemented = 'do not'
>>> NotImplemented
'do not'

意味着什么,什么时候用

NotImplemented是 python 特殊二元方法(例如__eq__(), __lt__(), __add__(), __rsub__())返回的特殊值,表示该操作没有针对其他类型实现。而且,它转换成 bool 类型表示 true

>>> bool(NotImplemented)
True

可能会有这样的疑问「应该在操作没有实现时抛出NotImpementedError异常」,通过一些例子,我们将看到为什么在实现二元特殊方法时不应该这样。

让我们通过为两个非常基本的(但无用的)类 A 和 B 编写一个 __eq__来展示NotImplemented常量的使用。[对于这个简单的例子,为避免分心不实现__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

现在在 interpreter 中:

>>> 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告诉运行时它应该请求 other 来满足操作。 在表达式b1 == a1中,b1 .__ eq __(a1)返回 NotImplemented,它告诉 Python 尝试调用 a1 .__ eq __(b1)。 由于 a1 足够知道返回 True,所以表达式可以成功。 如果 A 的__eq __()也返回NotImplemented,那么运行时将回退到基于对象标识(在 CPython 中是对象在内存中的地址)的相等内置行为。

注意,当b1 .__ eq __(a1)失败时抛出一个NotImpementedError异常会突破代码调用,除非被捕获,但 NotImplemented不会被抛出并可以用于进一步的测试。

原文:Python’s `NotImplemented` Type

扩展阅读:

极光日报,极光开发者旗下媒体。
每天导读三篇英文技术文章。

今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/DEqO9k2RNO
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/12327
 
381 次点击