如何让Python的数值类型子类的方法返回该子类的实例?

编程语言 2026-07-12

我天真地希望能够仅通过对Python的 Fraction 类进行子类化来添加一些缺失的方法。然而,这并没有按预期工作,因为这些方法返回 Fraction 的实例,而不是 F 的实例。

>>> from fractions import Fraction
>>> class F(Fraction): pass
... 
>>> x = F(1)
>>> x
F(1, 1)
>>> y = F(2)
>>> y
F(2, 1)
>>> x + y
Fraction(3, 1)

所以,看起来我需要对我这个类的实例在运算时的大多数运算符进行重载,使其返回该类的实例。这在某种程度上有点削弱了子类化的目的。

这是预期的行为吗?有没有办法绕过?

这个问题并不仅限于 Fraction。我认为对所有数值类都一样,也许不仅限于此。


相关问题与讨论:

解决方案

这是预期的行为吗?

是的,因为 Lib/fractions.py 中方法的实现明确返回 Fraction 的实例,而不是 type(self) 的实例(以加法为例,源代码请参阅 source)。

有没有办法绕过?

有,但不能通过子类实现。绕过的方法必须在 Fraction 自身实现,以允许对子类型的运算返回子类型的实例。这将通过让方法返回 type(self)(...) 而不是显式返回 Fraction 来实现。一个确实按这种方式工作方式的内置类型的例子是datetime:

>>> from datetime import datetime, timedelta
>>> class D(datetime):
...     pass
... 
>>> D(2026, 3, 7)
D(2026, 3, 7, 0, 0)
>>> D(2026, 3, 7) + timedelta(1)  # still a D instance, even though `__add__` wasn't overridden
D(2026, 3, 8, 0, 0)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章