为啥 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 => false
和NaN >= anything => false
。 (假设python遵循IEEE浮点逻辑)
是的,基本上任何没有total order 的东西都属于该类别。现在,由于显而易见的原因,这些东西有点罕见,但它们确实存在。 NaN 就是一个很好的例子。
但即使对于NaN
,它至少在python中也成立:NaN != NaN => True
,NaN == 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 系统中,equals
和not equals
不一定是彼此的精确倒数。
最明显的例子是 SQL,其中 True == True
、False == False
和 Null != Null
。虽然我不知道是否有任何特定的 Python 示例,但我可以想象它在某些地方实现。
【讨论】:
在mysql中,你甚至可以同时拥有NULL
和NOT NULL
的值!!!1! (我认为这是 MySQL 的设计错误)以上是关于为啥 Python 有一个 __ne__ 运算符方法而不仅仅是 __eq__?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Python 文档说我在定义 __eq__ 时需要定义 __ne__?
为啥 Python 没有“__req__”(反射相等)方法?
为啥 Counter 的 __init__ 方法称为描述符?