Class 没有函数工具的比较(如 __ge__)total_ordering

Class comparisons (like __ge__) without functools total_ordering

以下代码有效,但令人惊讶的是还适用于尚未实现的方法。 通常你需要 total_ordering 来完成这个,对吧?

class Account:

    def __init__(self, balance=0):
        self.balance = balance

    def __lt__(self, other):
        return self.balance < other.balance

    def __le__(self, other):
        return self.balance <= other.balance


acc1 = Account(100)
acc2 = Account(200)

print(acc1 < acc2)   # True
print(acc1 >= acc2)  # False, but __ge__ is not defined
print(acc1 == acc2)  # False, but __eq__ is not defined

在没有 total_ordering 的情况下这样做是否安全,或者这会导致意外吗?

这里发生了两件事。

首先是==默认总是定义,继承自object.__eq__。从本质上讲,它是按身份工作的,不是你在这里所期望的。

第二种是在documentation中描述的:

There are no swapped-argument versions of these methods (to be used when the left argument does not support the operation but the right argument does); rather, __lt__() and __gt__() are each other’s reflection, __le__() and __ge__() are each other’s reflection, and __eq__() and __ne__() are their own reflection.

所以,这就像 __add____radd__。在acc1 >= acc2的情况下,左操作数不支持__gt__,所以这个委托给右操作数的__le__.