子类化不可变类型时访问不可变部分的最优方法探究
子类化float并自定义加法行为的问题
初始实现
我想要为float创建一个子类,实现代码如下:
class MyFloat(float): def __new__(cls, number, extra): return super().__new__(cls, number) def __init__(self, number, extra): float.__init__(number) self.extra = extra
目前执行x = MyFloat(0.0, 'hi')后,x + 1会返回float类型的1.0,这符合预期,但我希望x + 1能返回MyFloat(1.0, 'hi')。
尝试中的递归问题
最初我想添加如下__add__方法:
def __add__(self, other): return MyFloat(self + other, self.extra)
但这会触发递归错误,因为代码会不断调用自身(注:我清楚两个MyFloat相加只会保留第一个的extra,这是简化示例)。
现有可行但粗糙的方案
目前有两种可行但不够优雅的实现方式:
- 转换为
float后计算:
def __add__(self, other): return MyFloat(float(self) + other, self.extra)
- 直接调用
float.__add__而非使用+运算符:
def __add__(self, other): return MyFloat(float.__add__(self, other), self.extra)
疑问
- 是否存在更Pythonic或更高效的处理方式?
- 在其他场景中需要访问实例的不可变部分时,比如要将
extra更新为f"{self+1.0}"(此处self指代不可变的数值部分),该如何实现?
速度测试更新
我做了一些速度测试,得到了有趣的结果:
- 使用
float.__add__(或super().__add__)的速度相对最慢,比基准代码慢20%以上; - 用
float(self)和float(other)转换为float的方式表现更好,比基准慢约15%; - 使用
self.real和other.real比基准慢约12%; - 最快的方法是使用
+self和+other,仅比基准慢6-8%——虽然原理看似与float(self)一致,但效率差异稳定。
想了解是否存在比+self更高效的方法?
内容的提问来源于stack exchange,提问作者Glen O
相关产品推荐
相关产品推荐

