在__add__运算符中返回相同子类的对象

Joh*_*hnQ 4 python inheritance overloading operator-overloading

我正在为自己的翻译开发一个简单的类型系统.我写的是这样的:

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)
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我做这样的事情,很明显:

if __name__ == '__main__':
    f1 = Float(3.5)
    f2 = Float(2.3)
    f3 = f1 + f2
    type(f3)
Run Code Online (Sandbox Code Playgroud)

我总结了f1和f2,它们是Float类型,但我已经获得了f3,这是Number类型,但我希望f3是Float类型.我如何在我的Number超类中定义我的add运算符一次返回一个与f1和f2相同的类型?我有没有使用isinstance?有更清洁的方法吗?

谢谢!

huo*_*uon 6

你可以做一些事情__class__:

def __add__(self, other):
    return self.__class__(self.content + other.content)
Run Code Online (Sandbox Code Playgroud)

至于@Eric指出,你可能想要做类似的事情

if self.__class__ == other.__class__:
    <use __class__>
else:
    <use Number>
Run Code Online (Sandbox Code Playgroud)

确保可预测的行为(或者如果类不匹配则执行其他操作).

__radd__ 在这里也值得重写:

__radd__ = __add__
Run Code Online (Sandbox Code Playgroud)

这将使 Number(1) + Float(1) == Float(1) + Number(1) == Float(2)