比较运算符与Python中的"丰富比较"方法

sch*_*tte 12 python comparison-operators python-2.7 python-3.x

有人可以解释我两者之间的差异.那些通常是等价的吗?也许我在这里完全错了,但我认为每个比较运算符都必然与一个"丰富的比较"方法有关.这来自文档:

运算符符号和方法名称之间的对应关系如下:

x<y电话x.__lt__(y),x<=y电话x.__le__(y),x==y电话x.__eq__(y),x!=y电话x.__ne__(y),x>y电话x.__gt__(y)x>=y电话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
Run Code Online (Sandbox Code Playgroud)

Python 2.x:

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

>>> dict1 < dict2
True
>>> dict1.__lt__(dict2)
NotImplemented
Run Code Online (Sandbox Code Playgroud)

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

我知道,与Python 2不同,在Python 3中,并非所有对象都支持比较运算符.令我惊讶的是,两个版本NotImplemented在通话时都会返回单身人士__lt__().

jua*_*aga 9

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

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

至于排序逻辑,这里是Python 2.7 文档:

当且仅当它们具有相等(键,值)对时,映射(dict的实例)才相等.键和值的相等比较强制实现反身性.

平等以外的结果一致地得到解决,但没有另外定义.

用脚注:

早期版本的Python使用了排序(键,值)列表的词典比较,但对于比较相等的常见情况,这是非常昂贵的.甚至早期版本的Python仅通过标识比较字典,但这引起了惊喜,因为人们希望能够通过将字典与{}进行比较来测试字典的空白.

而且,在Python 3.0中,订购已经简化.这来自文档:

(<, <=, >=, >)当操作数没有有意义的自然顺序时,排序比较运算符会引发TypeError异常.

builtin.sorted()并且list.sort()不再接受提供比较功能的cmp参数.请改用key参数.

cmp()函数应视为已消失,并且__cmp__()不再支持特殊方法.使用__lt__()的分类,__eq__()__hash__()根据需要,以及其他丰富的比较.(如果您确实需要该cmp()功能,可以使用该表达式(a > b) - (a <> b)作为等效项cmp(a, b).)

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

object.__cmp__(self, other)
如果没有定义丰富的比较(见上文),则通过比较操作调用.如果self <other则返回负整数,如果self == other则返回0,如果self> other则返回正整数.