Reputation: 2600
The following code works, but surprisingly also for the methods that have not been implemented. Normally you need total_ordering to accomplish this, right?
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
Is it safe to do this without total_ordering
or will this lead to surprises?
Upvotes: 1
Views: 87
Reputation: 96236
Two things are happening here.
The first is that ==
is always defined by default, inherited from object.__eq__
. Essentially it, works by identity, which is not what you expect here.
The second is described in the 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.
So, this is like __add__
and __radd__
. In the case of acc1 >= acc2
, the left operand does not support __gt__
, so this is delegated to the right operand's __le__
.
Upvotes: 2