有人可以解释一下两者之间的区别。那些通常是等价的吗?也许我在这里完全错了,但我认为每个比较运算符必然与一个“丰富的比较”方法相关。这来自文档:
运算符符号和方法名称之间的对应关系为 如下:
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
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__()
单身。
答案 0 :(得分:8)
这依赖于__cmp__
魔术方法,这是富比较运算符要替换的方法:
>>> dict1 = {1:1}
>>> dict2 = {2:2}
>>> dict1.__cmp__
<method-wrapper '__cmp__' of dict object at 0x10f075398>
>>> dict1.__cmp__(dict2)
-1
关于排序 logic ,这里是Python 2.7 documentation:
映射(dict的实例)比较相等,当且仅当它们有 等于(键,值)对。键和值的平等比较 强制反身性。
除了平等以外的结果会得到一致的解决,但事实并非如此 否则定义。
用脚注:
早期版本的Python使用了排序的词典比较 (键,值)列表,但这对于常见的情况非常昂贵 比较平等。比较早期的Python版本 只有身份的词典,但这引起了惊喜,因为 人们期望能够通过测试字典的空虚 将它与{}进行比较。
而且,在Python 3.0中,订购已经简化。这来自documentation:
排序比较运算符
(<, <=, >=, >)
引发TypeError 操作数没有有意义的自然顺序时的异常。
builtin.sorted()
和list.sort()
不再接受cmp参数 提供比较功能。改为使用key参数。
cmp()
函数应视为已消失,__cmp__()
特殊方法 不再受支持。使用__lt__()
进行排序,__eq__()
__hash__()
,以及其他必要的丰富比较。 (如果您确实需要cmp()
功能,则可以使用(a > b) - (a <> b)
表达式作为cmp(a, b)
的等效项。)
因此,为了明确,在Python 2中,由于未实现丰富的比较运算符,dict
对象将从数据模型documentation回退到__cmp__
:
object.__cmp__(self, other)
如果丰富,则通过比较操作调用 比较(见上文)未定义。应该返回负数 整数,如果自己&lt;其他,零如果自我==其他,正整数 如果自己&gt;其他
答案 1 :(得分:1)
操作员<
与__lt__
的注意事项:
import types
class A:
def __lt__(self, other): return True
def new_lt(self, other): return False
a = A()
print(a < a, a.__lt__(a)) # True True
a.__lt__ = types.MethodType(new_lt, a)
print(a < a, a.__lt__(a)) # True False
A.__lt__ = types.MethodType(new_lt, A)
print(a < a, a.__lt__(a)) # False False
在课堂上定义的 <
次调用__lt__
; __lt__
调用对象上定义的__lt__
。
它通常是相同的:)使用它是完全可口的:A.__lt__ = new_lt