多重继承场景下子类方法未被覆写的问题求助
问题:多重继承下无法覆写子类方法
我之前在实现避免代码重复的属性覆写方案时,遇到了多重继承相关的问题。给主类写了一个Interpolator类,主类里有个属性是SubClass的实例,现在没法覆写这个子类里的方法,求解决。
代码示例
import numpy as np class MyClass: def __init__(self): self._time = np.array([0, 1, 2, 3]) self._a = np.array([0, 1, 2, 3]) self._sub = SubClass() def _get_class_value(self, name): value = getattr(self, '_'+name) return value @property def time(self): return self._get_class_value('time') @property def a(self): print('calling a') return self._get_class_value('a') @property def sub(self): print('calling sub') return self._sub class SubClass: def __init__(self): self._k1 = np.array([0, 1, 2, 3]) def _get_sub_value(self, name): value = getattr(self, '_'+name) return value @property def k1(self): print('calling k1') return self._get_sub_value('k1') class Interpolator(MyClass, SubClass): def __init__(self, vector): super().__init__() self._vector = np.array(vector) def _get_class_value(self, name): print('overriding main class', name) return self._interpolate(name) def _get_sub_value(self, name): print('overriding sub class', name) return self._interpolate(name) def _interpolate(self, name): value = getattr(self, '_'+name) return np.interp(self._vector, self._time, value) interp = Interpolator([1.5, 2.5]) value_a = interp.a value_k1 = interp.sub.k1
实际运行输出
calling a overriding main class a calling sub calling k1
始终看不到'overriding sub class'的输出,这是为啥?
问题根源
interp.sub返回的是MyClass.__init__里直接创建的SubClass实例,这个实例和Interpolator完全没关系——它是原生的SubClass对象,调用的是自己的_get_sub_value方法,自然不会触发Interpolator里的覆写版本。你写的多重继承在这里完全没起作用,因为SubClass的实例是独立生成的,不是Interpolator的一部分。
解决方案
方案一:替换SubClass实例为自定义子类
修改MyClass的初始化逻辑,让子类可以替换_sub的实例,或者直接在Interpolator里重新赋值_sub:
import numpy as np class MyClass: def __init__(self): self._time = np.array([0, 1, 2, 3]) self._a = np.array([0, 1, 2, 3]) self._sub = self._create_sub() # 改成工厂方法,方便子类重写 def _create_sub(self): return SubClass() # 默认创建原生SubClass # 其他属性和方法不变... class SubClass: # 代码不变... # 先写一个SubClass的子类,覆写_get_sub_value class InterpolatedSub(SubClass): def __init__(self, parent): super().__init__() self.parent = parent # 关联到Interpolator实例 def _get_sub_value(self, name): print('overriding sub class', name) return self.parent._interpolate(name) class Interpolator(MyClass): def __init__(self, vector): super().__init__() self._vector = np.array(vector) self._sub = InterpolatedSub(self) # 替换成自定义的子类实例 def _get_class_value(self, name): print('overriding main class', name) return self._interpolate(name) def _interpolate(self, name): # 处理子类属性的取值 if name == 'k1': value = getattr(self._sub, '_'+name) else: value = getattr(self, '_'+name) return np.interp(self._vector, self._time, value) interp = Interpolator([1.5, 2.5]) value_a = interp.a value_k1 = interp.sub.k1
运行后就能看到overriding sub class k1的输出了。
方案二:用依赖注入传递插值逻辑
给SubClass加个可选的插值器参数,让它在需要时调用外部的插值逻辑:
import numpy as np class MyClass: def __init__(self, interpolator=None): self._time = np.array([0, 1, 2, 3]) self._a = np.array([0, 1, 2, 3]) self._sub = SubClass(interpolator) # 把插值器传给SubClass self.interpolator = interpolator # 其他属性和方法不变... class SubClass: def __init__(self, interpolator=None): self._k1 = np.array([0, 1, 2, 3]) self.interpolator = interpolator def _get_sub_value(self, name): # 如果有插值器,就用插值逻辑 if self.interpolator is not None: print('overriding sub class', name) return self.interpolator._interpolate(name, self) # 没有就用原生逻辑 value = getattr(self, '_'+name) return value # 其他属性不变... class Interpolator(MyClass): def __init__(self, vector): super().__init__(interpolator=self) # 把自己作为插值器传进去 self._vector = np.array(vector) def _get_class_value(self, name): print('overriding main class', name) return self._interpolate(name, self) def _interpolate(self, name, obj): # 根据传入的对象取值 value = getattr(obj, '_'+name) return np.interp(self._vector, self._time, value) interp = Interpolator([1.5, 2.5]) value_a = interp.a value_k1 = interp.sub.k1
这个方案更灵活,不需要创建子类,通过注入的方式让SubClass复用插值逻辑。
内容的提问来源于stack exchange,提问作者mauro
相关产品推荐
相关产品推荐

