19

In Python3, the functools.total_ordering decorator allows one to only overload __lt__ and __eq__ to get all 6 comparison operators.

I don't get why one has to write two operators when one would be enough, namely __le__ or __ge__, and all others would be defined accordingly :

a < b   <=>   not (b <= a)
a > b   <=>   not (a <= b)
a == b   <=>   (a <= b) and (b <= a)
a != b   <=>   (a <= b) xor (b <= a)

Is that just because xor operator does not exists natively?

4

1 回答 1

27

文档声明您必须定义 、 、 或 中的一个__lt__()__le__()__gt__()__ge__()提供一个__eq__()方法。

换句话说,该__eq__方法是可选的。

total_ordering实现不需要您指定__eq__方法;它只测试__lt__()__le__()__gt__()__ge__()方法。它提供了多达 3 种缺失的特殊方法,基于这 4 种方法之一。

你不能仅仅 __le__基于或者__ge__因为你不能假设你可以交换ab; if bis a different typeb.__le__可能无法实现,因此a < b <=> not (b <= a)无法保证您的地图。实现使用(a <= b) and (a != b)if__le__未定义但__lt__已定义。

完整的映射表是:

比较 可用的 选择
a > b a < b (not a < b) and (a != b)
a <= b (not a <= b)
a >= b (a >= b) and (a != b)
a <= b a < b (a < b) or (a == b)
a > b (not a > b)
a >= b (not a >= b) or (a == b)
a < b a <= b (a <= b) and (a != b)
a > b (not a > b) and (a != b)
a >= b (not a >= b)
a >= b a < b (not a < b)
a <= b (not a <= b) or (a == b)
a > b (a > b) or (a == b)

__eq__方法是可选的,因为基础object对象为您定义了一个;只有当它们是同一个对象时,两个实例才被认为是相等的;ob1 == ob2只有当ob1 is ob2True。见do_richcompare()函数object.c;请记住,==代码中的运算符是比较指针。

于 2013-04-26T13:59:58.193 回答