python - 比较运算符与 Python 中的 “rich comparison” 方法

标签 python python-3.x python-2.7 comparison-operators

谁能解释一下两者之间的区别。这些通常是等价的吗?也许我在这里完全错了,但我认为每个比较运算符都必然与一个“丰富比较” 方法相关。这是来自文档:

The correspondence between operator symbols and method names is as follows:

x<y calls x.__lt__(y), x<=y calls x.__le__(y), x==y calls x.__eq__(y), x!=y calls x.__ne__(y), x>y calls x.__gt__(y), and x>=y calls x.__ge__(y).

这是一个说明我的困惑的例子。

Python 3.x:

dict1 = {1:1}
dict2 = {2:2}

>>> dict1 < dict2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
>>> dict1.__lt__(dict2)
NotImplemented

Python 2.x:

dict1 = {1:1}
dict2 = {2:2}

>>> dict1 < dict2
True
>>> dict1.__lt__(dict2)
NotImplemented

从 python 3 示例来看,调用 dict1 < dict2 似乎是合乎逻辑的不支持。但是 Python 2 示例呢?为什么它被接受?

我知道与 Python 2 不同,在 Python 3 中,并非所有对象都支持比较运算符。但令我惊讶的是,这两个版本都返回了 NotImplemented调用时单例 __lt__() .

最佳答案

这依赖于__cmp__魔术方法,这是富比较运算符要替换的东西:

>>> dict1 = {1:1}
>>> dict2 = {2:2}
>>> dict1.__cmp__
<method-wrapper '__cmp__' of dict object at 0x10f075398>
>>> dict1.__cmp__(dict2)
-1

关于排序逻辑,这是 Python 2.7 documentation :

Mappings (instances of dict) compare equal if and only if they have equal (key, value) pairs. Equality comparison of the keys and values enforces reflexivity.

Outcomes other than equality are resolved consistently, but are not otherwise defined.

带脚注:

Earlier versions of Python used lexicographic comparison of the sorted (key, value) lists, but this was very expensive for the common case of comparing for equality. An even earlier version of Python compared dictionaries by identity only, but this caused surprises because people expected to be able to test a dictionary for emptiness by comparing it to {}.

而且,在 Python 3.0 中,排序得到了简化。这是来自 documentation :

The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.

builtin.sorted() and list.sort() no longer accept the cmp argument providing a comparison function. Use the key argument instead.

The cmp() function should be treated as gone, and the __cmp__() special method is no longer supported. Use __lt__() for sorting, __eq__() with __hash__(), and other rich comparisons as needed. (If you really need the cmp() functionality, you could use the expression (a > b) - (a <> b) as the equivalent for cmp(a, b).)

因此,明确地说,在 Python 2 中,由于没有实现丰富的比较运算符,dict对象将回退到 __cmp__ , 来自数据模型 documentation :

object.__cmp__(self, other)
Called by comparison operations if rich comparison (see above) is not defined. Should return a negative integer if self < other, zero if self == other, a positive integer if self > other.

关于python - 比较运算符与 Python 中的 “rich comparison” 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47797346/

相关文章:

Python打印对象设计

python - QGridLayout 小部件重叠

python - "while A:"中的 A 调用了什么操作?

python - 如何在 2 列表 python 3 之间提取列表?

python - 使用 JMESPath 基于另一个查询结果过滤列表

python-3.x - Spyder 忽略 .pycodestyle

python - 尝试,除了 ValueError 替换为 None

python - 是否有代码可以对列中包含的相似单词进行分组

python - igraph 绘制图表 : Killed 9

python - 构建和比较时间