【发布时间】:2013-11-22 01:49:31
【问题描述】:
在 Python (2.7) 中,我想创建一个有理数类,它模仿 Fraction 类的行为(在模块分数中)但覆盖 __repr__ 方法以匹配 __str__ 的结果。最初的想法只是为了我自己的修补,只是为了让 IDLE 输出看起来更友好。但现在我更感兴趣的是理解潜在的继承/类型问题——我认为这可能是普遍的兴趣——而不是为这个特定的用例找到一个解决方法,这无疑是微不足道的。
问题是,我也想继承所有数值运算符(方法 __add__、__sub__ 等)的功能,但结果是我的子类的实例而不是 Fraction 的实例。这就是我想要的,但是却发生了这种情况:
class Q(Fraction):
def __repr__(self):
return str(self)
>>> Q(1,2)
1/2
>>> Q(1,2) + Q(1,3)
Fraction(5, 6)
这是因为 Fraction 中定义的运算符返回 Fraction 实例。当然,我可以单独覆盖所有这些魔术方法,调用父类进行数学运算,然后强制转换为我的类型,但我觉得应该有一种方法可以通用地处理这种重复的情况(即不写“def”20次)。
我也考虑过使用 __getattribute__ 来拦截方法调用,但这看起来很不优雅,非常脆弱,并且在比这个稍微复杂一点的情况下几乎肯定会失败。 (我知道 __getattr__ 是首选,但似乎不会捕获我感兴趣的方法调用,因为它们是在基类中定义的!)
鉴于我不是基类的作者,有没有比单独覆盖每个方法更好的方法?
【问题讨论】:
-
不幸的是,您必须定义所有魔术方法。 (
__geattribute__不起作用,它不会捕获对魔术方法的魔术调用。)但是,您可以使用here 描述的方法自动创建此类方法。基本上,您编写一个元类,它会自动定义调用基类魔术方法并将结果包装在派生类中的魔术方法。 -
所以主要问题是您的基类
Fraction没有很好地为继承而设计。如果是这样,它会使用类似type(self)(...)的东西来创建它返回的对象(或它显示的repr-strings)。不幸的是,这意味着它会让你的生活更加艰难。
标签: python inheritance