max*_*max 7 python equality python-3.x python-internals
NotImplemented从__eq__python 3中的特殊方法返回的结果是什么(如果重要,则为3.5)?
文件不清楚; 我发现的唯一相关文字只是模糊地提到"其他一些后备":
当
NotImplemented返回时,解释器将尝试在其他类型的,或其他一些后备的反射操作,取决于运营商.如果所有尝试的操作都返回NotImplemented,则解释器将引发适当的异常.有关更多详细信息,请参阅实现算术运算.
不幸的是,"更多细节"链接根本没有提到__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
Run Code Online (Sandbox Code Playgroud)
从实验开始,我认为当NotImplemented返回时__eq__,解释器的行为就好像__eq__首先没有定义一样(具体来说,它首先交换参数,如果这不能解决问题,它会使用__eq__评估的默认值进行比较)如果两个对象具有相同的身份,则"相等").如果是这种情况,我可以在文档中找到此行为的确认吗?
编辑:请参阅Python issue 28785
MSe*_*ert 13
实际上==and !=check 的工作与排序比较运算符(<和类似运算符)相同,只是它们不会引发适当的异常,而是回退到身份比较。这是唯一的区别。
这可以在CPython 源代码(版本 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
Run Code Online (Sandbox Code Playgroud)
并调用a == b然后评估为richcmp(a, b, '__eq__')。这if op == '__eq__'是使您a == b返回False(因为它们不是相同的对象)和a == a返回True(因为它们是)的特殊情况。
然而,Python 2.x 中的行为完全不同。在回退到身份比较之前,您最多可以进行 4 次(甚至 6 次,我记不太清了)比较!
不确定它在文档中的位置(或是否),但基本行为是:
__eq__(lhs, rhs)NotImplemented返回它__eq__(rhs, lhs)NotImplemented返回它否则使用适当的回退:
eq -> 相同的对象?-> 真,否则假
ne -> 不同的对象?真,否则假
许多其他 -> 引发异常
其原因eq和ne根本没有引发异常是:
| 归档时间: |
|
| 查看次数: |
1045 次 |
| 最近记录: |