【问题标题】:Returning object of same subclass in __add__ operator在 __add__ 运算符中返回相同子类的对象
【发布时间】:2013-05-20 22:38:09
【问题描述】:

我正在为自己的解释器开发一个简单的类型系统。 我正在写这样的东西:

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)

我的问题显然是如果我这样做:

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

我将f1和f2相加,它们是Float类型,但我得到了f3,它是Number类型,但我希望f3是Float类型。如何在 Number 超类中定义一次 add 运算符,返回一个与 f1 和 f2 相同的类型?我必须使用 isinstance 吗?有没有更清洁的方法来做到这一点?

谢谢!

【问题讨论】:

    标签: python inheritance operator-overloading overloading


    【解决方案1】:

    你可以用__class__做点什么:

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

    正如@Eric 指出的那样,你可能想做一些类似

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

    以确保可预测的行为(或在类不匹配时采取其他行动)。

    __radd__ 也值得在这里覆盖:

    __radd__ = __add__
    

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

    【讨论】:

    • 你可能需要仔细考虑是要self.__class__还是other.__class__
    • 哦,谢谢。它完美地工作。我以为 Number 类中的 self.__class__ 会等于 'Number'...我错了。
    • 为了进一步扩展,我想你想要{(1, 0): self.__class__, (0, 1): other.__class__}.get((issubclass(self.__class__, other.__class__), issubclass(other.__class__, self.__class__)), Number)。如果我不必将它放在评论中,那将不那么迟钝。
    • 实际上,放弃它。只要别名__radd__,python 会处理好事情
    • @Eric,请随时将其编辑到我的答案中,因为那里会更清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2015-04-06
    相关资源
    最近更新 更多