在 __add__ 运算符中返回相同子类的对象
Posted
技术标签:
【中文标题】在 __add__ 运算符中返回相同子类的对象【英文标题】:Returning object of same subclass in __add__ operator 【发布时间】: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 吗?有没有更清洁的方法来做到这一点?
谢谢!
【问题讨论】:
【参考方案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,请随时将其编辑到我的答案中,因为那里会更清楚。以上是关于在 __add__ 运算符中返回相同子类的对象的主要内容,如果未能解决你的问题,请参考以下文章