Reputation: 1428
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 :)
Upvotes: 2
Views: 868
Reputation: 21
Sounds like you're wanting to test for what kind of object you are working with. Maybe something like:
import numbers
def __gt__(self, other):
if isinstance(other, type(self)):
return self.a * other.b > other.a * self.b
elif isinstance(other, numbers.Number):
return self.a > other
else:
err_str = "Unknown type in comparison with %s object: %s" % (type(self).__name__, type(other).__name__)
raise(TypeError(err_str))
Here, type(self) is a generic way of getting the CRational class. That way you don't have to modify the class's code if you simply change the name later.
isinstance checks to see if a given object is of the given type, or a child type. Python documentation.
I made up the numeric case, because I don't know how you'd want to define that.
Upvotes: 2
Reputation: 15384
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.
Upvotes: 4
Reputation: 1385
With regards to your error output: you are getting the error because your "other" is an int and CRational.__gt__
is trying to access an attribute that it does not have a b
:
def __gt__(self, other): # passing in an int here
return self.a * other.b > other.a * self.b
With regards to your code example, assuming a
is another CRational
object, then a > 0
will cause the AttributeError
you are seeing above and the only way to fix it is by comparing it with either another CRational
object or some other object that has attribues a
and b
.
Upvotes: 2