+ 2
Python Operator Overloading
Hello coders! In the following example I overloaded __lt__ magic method with different behavior for â<â sign, but when I use â>â (__gt__) it behaves the same. Could you please explain, is there any connection between these two operators? class Text: def __init__(self,food): self.food = food def __lt__(self,other): print(455) obj_A = Text("Apple") obj_B = Text("Mushroom") obj_A < obj_B obj_A > obj_B
10 Answers
+ 4
If you want to override the comparison operator for your custom objects, it is worth reviewing what the documentation has to say about this.
https://docs.python.org/3/reference/datamodel.html#customization
A few highlights:
By convention, False and True are returned for a successful comparison. However, these methods can return any value, so if the comparison operator is used in a Boolean context (e.g., in the condition of an if statement), Python will call bool() on the value to determine if the result is true or false.
By default, object implements __eq__() by using is, returning NotImplemented in the case of a false comparison: True if x is y else NotImplemented. For __ne__(), by default it delegates to __eq__() and inverts the result unless it is NotImplemented.
__lt__() and __gt__() are each otherâs reflection
+ 3
The __lt__ is the opposit of __gt__
When you run this code
def __lt__(self,other):
return other.food
obj_A = Text("Apple")
obj_B = Text("Mushroom")
print(obj_A < obj_B)
print(obj_A > obj_B)
The output would be
Mushroom
Apple
I think shoud be consider this
+ 3
Ruslan Guliyev
you did not actually do a comparison in your __lt__ override. Since there are no comparison parameter, python just use the same condition for __gt__.
here is a fun way of reversing gt and lt
class Reversed:
def __init__(self,n):
self.n = n
def __lt__(self,other):
#using '>' instead of '<'
return self.n>other.n
def __repr__(self):
return f'{self.n}'
x = Reversed(100)
y = Reversed(0)
print(f'{x = }')
print(f'{y = }')
# '<' behavior reversed
print(f'{x} < {y} : {x<y}')
# '>' behavior is also reversed
print(f'{x} > {y} : {x>y}')
+ 3
If > isn't implemented,
Obj_A > Obj_B
is evaluated as
Obj_B < Obj_A
Note that in "normal" math, the two expressions are equivalent. You can, however, define them differently, if you like.
The reverse is also true:
If < isn't implemented,
Obj_A < Obj_B
is evaluated as
Obj_B > Obj_A
+ 2
__lt__ is "less than", not "it".
The reflection means sort of a mirror image.
If you define "less than" operator, then you can use a < b between objects and you can also use a > b which returns the opposite result (True vs False)
+ 1
Ab SH, Thank you for your response!
As I understand __lt__ would behave opposite of __gt__ only in case of overloading, I mean when I change the functionality. Is it correct?
+ 1
Bob_Li, Thank you! It is very interesting example.
For me it is mostly interesting how are these two magic methods interconnected underhood and why they affect each other.
+ 1
Tibor Santa, thank you for your response!
It is a bit difficult for me to understand everything from the documenation. As you mentioned __it__ and __gt__ are reflection of each other, does it mean that they can output the same result like in my example?
+ 1
Ruslan Guliyev, Equivalent means that, if one expression is true, then so is the other, and vice versa.
In this case, if one object is lower than the other, then the other is greater than the one.
For example,
2 < 3 (2 is lower than 3) is true, and
3 > 2 (3 is greater than 2) is also true.
So when trying to find out whether
x < y is true,
one might instead look at whether
y > x is true, and give the same result.
0
Marijke van Bommel, Thank you for your response!
Could please elaborate more on what you meant by equivalence of these operators? How are they connected?
For me it is mostly interesting why they output the same result..