Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning object of same subclass in __add__ operator

I am developing a simple type system for my own interpreter. I am writing something like this:

class Base(object):
    def __init__(self, content):
        self.__content = content

    @property
    def content(self):
        return self.__content

    @content.setter
    def content(self, value):
        self.__content = value

class Number(Base):
    def __init__(self, content):
        super(Number, self).__init__(content)

    def __add__(self, other):
        return Number(self.content + other.content)

    ...and so on

class Float(Number):
    def __init__(self, content):
        super(Float, self).__init__(content)

class Integer(Number):
    def __init__(self, content):
        super(Integer, self).__init__(content)

My problem is that obviously if I do something like this:

if __name__ == '__main__':
    f1 = Float(3.5)
    f2 = Float(2.3)
    f3 = f1 + f2
    type(f3)

I have summed f1 and f2, which are Float type, but I have obtained f3, which is Number type, but I would like f3 to be a Float type. How could I define my add operator just one time in my Number superclass returning a type which is the same of f1 and f2? Have I to use isinstance? Is there a cleaner way to do this?

Thank you!

like image 708
JohnQ Avatar asked May 25 '13 13:05

JohnQ


1 Answers

You could do something with __class__:

def __add__(self, other):
    return self.__class__(self.content + other.content)

As, @Eric points out, you may want to do something like

if self.__class__ == other.__class__:
    <use __class__>
else:
    <use Number>

to ensure predicable behaviour (or some other action if the classes don't match).

__radd__ is also worth overriding here:

__radd__ = __add__

which will make Number(1) + Float(1) == Float(1) + Number(1) == Float(2)

like image 156
huon Avatar answered Oct 01 '22 14:10

huon