为啥 Python 有一个 __ne__ 运算符方法而不仅仅是 __eq__?

Posted

技术标签:

【中文标题】为啥 Python 有一个 __ne__ 运算符方法而不仅仅是 __eq__?【英文标题】:Why does Python have an __ne__ operator method instead of just __eq__?为什么 Python 有一个 __ne__ 运算符方法而不仅仅是 __eq__? 【发布时间】:2012-03-16 04:32:21 【问题描述】:

答案here 给出了一个挥手引用的情况,您希望__ne__ 返回的东西不仅仅是__eq__ 的逻辑逆,但我无法想象任何这样的情况。有什么例子吗?

【问题讨论】:

至少><=有这样的情况。即NaN < anything => falseNaN >= anything => false。 (假设python遵循IEEE浮点逻辑) 是的,基本上任何没有total order 的东西都属于该类别。现在,由于显而易见的原因,这些东西有点罕见,但它们确实存在。 NaN 就是一个很好的例子。 但即使对于NaN,它至少在python中也成立:NaN != NaN => TrueNaN == NaN => False equals (__eq__) 可能不会返回 Boolean 类型而 not equals (__ne__) 可能不会 与等于相反...违背所有直觉。 - 我接受它作为 Python 方式。我想它有它的好处,正如答案所解释的那样。然而,对于刚接触这门语言的人来说,这真是令人毛骨悚然。 【参考方案1】:

有些库会做一些花哨的事情,并且不会从这些操作中返回布尔值。例如,使用 numpy:

>>> import numpy as np
>>> np.array([1,2,5,4,3,4,5,4,4])==4
array([False, False, False,  True, False,  True, False,  True,  True], dtype=bool)
>>> np.array([1,2,5,4,3,4,5,4,4])!=4
array([ True,  True,  True, False,  True, False,  True, False, False], dtype=bool)

当您将数组与单个值或另一个数组进行比较时,您会得到一个布尔数组,其中包含比较相应元素的结果。如果x!=y 简单地等同于not (x==y),你就不能这样做。

【讨论】:

我听不懂。考虑到not 以明显的方式定义在一个布尔数组上,我们仍然不需要neq 而不是not equals。但显然那里有性能和可能的内存优势。 虽然可以为 __not__ 特殊方法提供一个很好的参数来覆盖 not 运算符,但目前 Python 中不存在这种方法。 哦,这太令人惊讶了。是的,在这种情况下,这不仅仅是性能问题。谢谢! @Weeble Unary invert (__invert__) 工作:~np.array([True, False]) -> array([False, True])。虽然我不确定 2012 年的情况是否相同。【参考方案2】:

SQLAlchemy 就是一个很好的例子。对于初学者来说,SQLAlchemy 是一个 ORM,它使用 Python 表达式来生成 SQL 语句。在诸如

之类的表达式中
meta.Session.query(model.Theme).filter(model.Theme.id == model.Vote.post_id)

model.Theme.id == model.VoteWarn.post_id 不返回一个布尔值,而是一个最终产生像WHERE theme.id = vote.post_id 这样的 SQL 查询的对象。反过来会产生类似WHERE theme.id <> vote.post_id 的东西,所以这两种方法都需要定义。

【讨论】:

【参考方案3】:

更一般地,在many valued logic 系统中,equalsnot equals 不一定是彼此的精确倒数。

最明显的例子是 SQL,其中 True == TrueFalse == FalseNull != Null。虽然我不知道是否有任何特定的 Python 示例,但我可以想象它在某些地方实现。

【讨论】:

mysql中,你甚至可以同时拥有NULLNOT NULL的值!!!1! (我认为这是 MySQL 的设计错误)

以上是关于为啥 Python 有一个 __ne__ 运算符方法而不仅仅是 __eq__?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Python 文档说我在定义 __eq__ 时需要定义 __ne__?

Python的双下划方法

为啥 Python 没有“__req__”(反射相等)方法?

为啥 Counter 的 __init__ 方法称为描述符?

为啥列表有 __reverse__() 特殊方法但元组在 Python 中没有?

为啥 Python 新式类中的 __new__ 不是类方法?