Alex Bachurin
Alex Bachurin

Reputation: 47

Magic methods with > 1 operands between MyClass and standard Class

Imagine I want to define a new number class. Say, RationalFractions or GaussIntegers, whatever. Of course, I can easily define a + b for two objects of MyClass. But i would like to be able to add an object of MyClass with some existing, like "integer" or "float". With the result having a relevant type (from my point of view). E.g. the result of GaussInteger + float = GaussInteger, RationalFraction + integer = RationalFraction, etc. I guess I should somehow alter add for Object class, or "integer", "float"? Or there is a way to do it without meddling with the existing classes?

Edit. So, an example:

class RatFr:

    def __init__(self, m, n=1):
        self.m = m
        self.n = n

    def __add__(self, other):
        temp = (RatFr(other) if type(other) == int else other)
        return RatFr(self.m * temp.n + self.n * temp.m, self.n * temp.n)

    def __str__(self):
        return f'{self.m}/{self.n}'


    a = RatFr(5,3)
    b = 1
    print(a)
    print(a + b)
    print(b + a)

I get as a result:

5/3
8/3
Traceback (most recent call last):
File "/Users/aleksej/PycharmProjects/Alex2/playaround.py", line 19, in <module>
print(b + a)
TypeError: unsupported operand type(s) for +: 'int' and 'RatFr'

Trying to convert self does nothing good. As soon as the first operand is int, python obviously looks for integer add method.

Upvotes: 2

Views: 43

Answers (1)

HackerBoss
HackerBoss

Reputation: 829

Yes. You will want to override __add__ from object, taking self and say x as parameters. You can then deal with x according to its type. Here you have a few options. You can do explicit type checking, but this is not very Pythonic. I would probably make a conversion function to convert from int, float, etc to your type and call it on x. Then you can do whatever addition would do between two objects of your type. This sort of call to a conversion function before doing an operation is done in the mpmath library, in the backend. Remember that you will need to check if the thing you are converting is already the right type.

Upvotes: 1

Related Questions