gpt4 book ai didi

python - 从 __eq__ 返回 NotImplemented

转载 作者:太空狗 更新时间:2023-10-29 21:54:26 25 4
gpt4 key购买 nike

从 python 3 中的 __eq__ 特殊方法返回 NotImplemented 的结果是什么(如果重要,则为 3.5)?

文档不清晰; only relevant text I found仅含糊地提到“其他一些后备”:

When NotImplemented is returned, the interpreter will then try the reflected operation on the other type, or some other fallback, depending on the operator. If all attempted operations return NotImplemented, the interpreter will raise an appropriate exception. See Implementing the arithmetic operations for more details.

不幸的是,“更多详细信息”链接根本没有提到 __eq__

我对这段摘录的阅读表明下面的代码应该引发“适当的异常”,但它没有:

class A:
def __eq__(self, other):
return NotImplemented

class B:
def __eq__(self, other):
return NotImplemented

# docs seems to say these lines should raise "an appropriate exception"
# but no exception is raised
a = A()
b = B()
a == b # evaluates as unequal
a == a # evaluates as equal

根据实验,我认为当 __eq__ 返回 NotImplemented 时,解释器的行为就好像 __eq__ 没有在第一个中定义放置(具体来说,它首先交换参数,如果这不能解决问题,它会使用默认的 __eq__ 进行比较,如果两个对象具有相同的身份,则评估为“相等”)。如果是这种情况,我可以在文档的哪个位置找到对此行为的确认?

编辑:参见 Python issue 28785

最佳答案

实际上是==!=检查工作与排序比较运算符(< 和类似)相同,只是它们不会引发适当的异常,而是回退到身份比较。这是唯一的区别。

这可以很容易地在 CPython source code (version 3.5.10) 中看到.我将包括该源代码的 Python 版本(至少尽可能):

_mirrored_op = {'__eq__': '__eq__',  # a == b => b == a
'__ne__': '__ne__', # a != b => b != a
'__lt__': '__gt__', # a < b => b > a
'__le__': '__ge__', # a <= b => b >= a
'__ge__': '__le__', # a >= b => b <= a
'__gt__': '__lt__' # a > b => b < a
}

def richcmp(v, w, op):
checked_reverse = 0
# If the second operand is a true subclass of the first one start with
# a reversed operation.
if type(v) != type(w) and issubclass(type(w), type(v)) and hasattr(w, op):
checked_reverse = 1
res = getattr(w, _mirrored_op[op])(v) # reversed
if res is not NotImplemented:
return res
# Always try the not-reversed operation
if hasattr(v, op):
res = getattr(v, op)(w) # normal
if res is not NotImplemented:
return res
# If we haven't already tried the reversed operation try it now!
if not checked_reverse and hasattr(w, op):
res = getattr(w, _mirrored_op[op])(v) # reversed
if res is not NotImplemented:
return res
# Raise exception for ordering comparisons but use object identity in
# case we compare for equality or inequality
if op == '__eq__':
res = v is w
elif op == '__ne__':
res = v is not w
else:
raise TypeError('some error message')

return res

并调用 a == b然后计算为 richcmp(a, b, '__eq__') . if op == '__eq__'是使您的 a == b 的特例返回 False (因为它们不是相同的对象)和你的 a == a返回 True (因为他们是)。

但是 Python 2.x 中的行为完全不同。在回到身份比较之前,您最多可以进行 4 次(甚至 6 次,我记不太清了)比较!

关于python - 从 __eq__ 返回 NotImplemented,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40780004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com