- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
从 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 returnNotImplemented
, 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/
根据 this page , set.intersection 使用 __eq__ 方法测试元素是否相等。谁能向我解释为什么这会失败? >>> Class Foo(object): >>> d
所以下面的内置类有一个 __eq__ 属性,(我假设)这就是为什么你可以测试它们的实例是否相等: >>> 1.2.__eq__( 1.2 ) True >>> 1.2 == 1.2 True >>>
在我正在处理的问题中,数据标识符的形式为 scope:name,既是 scope 又是 name 字符串. name 由点分隔的不同部分,如 part1.part2.part3.part4.part5
我有一组对象,并且有兴趣从该组中获取特定对象。经过一番研究,我决定使用此处提供的解决方案:http://code.activestate.com/recipes/499299/ 问题是它似乎不起作用。
我有一个父数据类和一个子数据类继承第一个类。我重新定义了__eq__()父数据类中的方法。但是当我比较对象子数据类时,它不使用 __eq__()父数据类中定义的方法。为什么会发生这种情况?我该如何解决
我正在用 Python 编写 DSL,我想重载运算符以便能够轻松编写 DSL 的表达式。例如,我想编写 Var("a") + Var("b") 并获得 Add(Var("a"), Var("b") 的
如果我像这样在 Python 2.7 中定义一个对象: class C(object): def __eq__(self, other): return object.__eq
目前,我正在研究 Python 的内置类型。我很困惑调用什么方法来检查键是否在字典中。例如,如果我检查 int 类型的键是否在字典中,则仅当 dictionary.keys() 包含它时,才会在后台调
我读过这个(来自 here ): User-defined classes have __eq__() and __hash__() methods by default; with them, al
在将功能移植到程序的 Python 3.1 分支时,我遇到了一个奇怪的错误。我将其缩小为以下假设: 与 Python 2.x 相比,在 Python 3.x 中,如果对象具有 __eq__ 方法,则它
我有一个类型,其中相等比较没有意义。明确比较此类型的两个实例的引用或值相等性将指示调用代码中的逻辑错误。 定义 __eq__ 引发异常是不是很糟糕?这有什么陷阱吗?它是否作为某些常见操作的一部分被隐式
我有一个Python程序,其中有一个名为Vector的类,并且该类内部有一个空列表,该列表正在运行时填充。这是初始化: def __init__(self,n): self.vector =
以下代码给出错误信息: class Test(object): def __init__(self, test = 0): self.test = test if __
我还有一个问题要问你。 我有一个带有列表“元信息”的 python 类。此列表包含我的类可能 包含的变量名称。我编写了一个 __eq__ 方法,如果 self 和 other 具有来自 metainf
我正在处理一个集合类,我想为其创建一个 __eq__ 方法。事实证明,它比我想象的要微妙得多,而且我注意到内置集合类的工作方式有几个错综复杂的地方。 真正对我帮助最大的是一个很好的例子。在标准库或任何
假设我有以下程序: class A(object):
为类实现自定义相等函数时,首先检查身份是否有意义?一个例子: def __eq__(self, other): return (self is other) or (other criteri
当我尝试重写魔术方法 __eq__,并使用 super 访问 object 中的基本方法时,出现错误.这不可能是一个错误,但感觉确实像一个错误: class A(object): def __
我遇到了一个问题,我将一个实例添加到一个集合中,然后进行测试以查看该对象是否存在于该集合中。我已经重写了 __eq__() 但在包含测试期间它没有被调用。我是否必须改写 __hash__()?如果是这
在将功能移植到我的程序的 Python 3.1 分支时,我遇到了一个奇怪的错误。我将其缩小到以下假设: 与 Python 2.x 相比,在 Python 3.x 中,如果一个对象具有 __eq__ 方
我是一名优秀的程序员,十分优秀!