why defining only __lt__ makes > operation possible?
Question:
class Node:
def __init__(self,a,b):
self._a=a
self._b=b
def __lt__(self,other):
return self._a<other._a
a=Node(1,2)
b=Node(0,4)
print(a>b)
The code above shows True.
class Node:
def __init__(self,a,b):
self._a=a
self._b=b
def __lt__(self,other):
return self._a<other._a
def __eq__(self,other):
return self._a==other._a
a=Node(1,2)
b=Node(0,4)
print(a>=b)
The code above shows TypeError: ‘<=’ not supported between instances of ‘Node’ and ‘Node.
Why defining only lt makes >(which is gt) operation possible?
why defining both lt and eq makes <= impossible?
Answers:
The Python docs dictates:
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 if the left-hand-side argument doesn’t implement a comparison operator while the right-hand-side implements its reflection, that reflection is called instead. This also explains why Python doesn’t combine __lt__()
and __eq__()
into __le__()
— it simply isn’t considered.
In the first example you are comparing with >
, which uses __gt__
. In the second example you are comparing with >=
, which is a different comparison, and it uses __ge__
.
Have a look at rich comparison at the docs
These are the so-called “rich comparison” methods. The correspondence
between operator symbols and method names is as follows: x<y
calls
x.__lt__(y)
, x<=y
calls x.__le__(y)
, x==y
calls x.__eq__(y)
, x!=y
calls x.__ne__(y)
, x>y
calls x.__gt__(y)
, and x>=y
calls x.__ge__(y)
.
class Node:
def __init__(self,a,b):
self._a=a
self._b=b
def __lt__(self,other):
return self._a<other._a
a=Node(1,2)
b=Node(0,4)
print(a>b)
The code above shows True.
class Node:
def __init__(self,a,b):
self._a=a
self._b=b
def __lt__(self,other):
return self._a<other._a
def __eq__(self,other):
return self._a==other._a
a=Node(1,2)
b=Node(0,4)
print(a>=b)
The code above shows TypeError: ‘<=’ not supported between instances of ‘Node’ and ‘Node.
Why defining only lt makes >(which is gt) operation possible?
why defining both lt and eq makes <= impossible?
The Python docs dictates:
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 if the left-hand-side argument doesn’t implement a comparison operator while the right-hand-side implements its reflection, that reflection is called instead. This also explains why Python doesn’t combine __lt__()
and __eq__()
into __le__()
— it simply isn’t considered.
In the first example you are comparing with >
, which uses __gt__
. In the second example you are comparing with >=
, which is a different comparison, and it uses __ge__
.
Have a look at rich comparison at the docs
These are the so-called “rich comparison” methods. The correspondence
between operator symbols and method names is as follows:x<y
calls
x.__lt__(y)
,x<=y
callsx.__le__(y)
,x==y
callsx.__eq__(y)
,x!=y
callsx.__ne__(y)
,x>y
callsx.__gt__(y)
, andx>=y
callsx.__ge__(y)
.