Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: overload operator > with different types

tell me how to overload the operator > (lt) or < (gt) etc so that it can work with different types (especially with 0)

for example:

class CRational(object):

    def __init__(self, a = 0, b = 1):
        self.a = a
        self.b = b
        
    def __neg__(self):
        return CRational(-self.a, self.b)

    def __add__(self, other):
        return CRational(self.a * other.b + other.a * self.b, self.b * other.b)

    def __sub__(self, other):
        return CRational(self.a * other.b - other.a * self.b, self.b * other.b)

    def __mul__(self, other):
        return CRational(self.a * other.a, self.b * other.b)

    def __truediv__(self, other):
        return CRational(self.a * other.b, self.b * other.a)

    def __eq__(self, other):
        return self.a * other.b == other.a * self.b

    def __ne__(self, other):
        return not self.__eq__(other)

    def __lt__(self, other):
        return self.a * other.b < other.a * self.b

    def __le__(self, other):
        return self.a * other.b <= other.a * self.b

    def __gt__(self, other):
        return self.a * other.b > other.a * self.b

    def __ge__(self, other):
        return self.a * other.b >= other.a * self.b

error output:

File "lessons/python/square_eq.py", line 66, in __gt __ return self.a * other.b > other.a * self.b AttributeError: 'int' object has no attribute 'b'

in code:

s_a = "" if a > 0 else "-"

how do you fix it?

s_a = "" if a > CRational(0) else "-"

the method described above helps, but it is not beautiful :)

like image 671
Zhihar Avatar asked Aug 05 '26 13:08

Zhihar


1 Answers

If you want to compare a CRational object with an int then your __gt__ method should works with integers too. I.e., if other is an integer, you clearly can't do something like other.b. Here is a possible solution:

class CRational:
    def __init__(self, a = 0, b = 1):
        self.a = a
        self.b = b
    def __gt__(self, other):
        if isinstance(other, CRational):
            return self.a * other.b > other.a * self.b
        elif isinstance(other, int):
            # Compare self (a CRational object) with other (an int)
            # TODO
        else:
            raise NotImplemented()

Now you can do something like this:

a = CRational()
if a > 3:
    ...

Be careful though! Even if you implement correctly all the methods, you still can't do 3 > a. Order is important!! 3 > a would call the __gt__ method of the int class. You can only do a > 3, a < 3, a >= 3 etc.

like image 78
Riccardo Bucco Avatar answered Aug 08 '26 08:08

Riccardo Bucco