如何减少父类初始化次数,优化基于继承的正弦波绘制代码?
优化正弦波绘制的类结构与运行效率
原代码通过类继承实现不同频率、振幅的正弦波绘制,但存在效率问题——内部循环中每个时间点都实例化Child类,导致重复调用父类__init__初始化相同的f(频率)、a(振幅)和颜色值,造成不必要的性能损耗。需求是针对每组(f,a)仅初始化一次公共属性,内部循环仅处理时间变量t。
原代码:
import math from matplotlib import pyplot as plt class Parent: def __init__(self, f, a): self.freq = f self.ampl = a self.color = (f/a/3, (f/a)/2, (f/a)) # 随机RGB颜色 class Child(Parent): def __init__(self, t, f, a): super(Child, self).__init__(f, a) self.time = t def volt(self): omega = 2*math.pi*self.freq return self.ampl * math.sin(omega*self.time) if __name__ == '__main__': for (f,a) in [(0.05,1.5), (0.1,1)]: color = Parent(f, a).color time = [i for i in range(50)] cl = [Child(x, f, a).volt() for x in time] plt.plot(time, cl, color=color) plt.xlabel("time") plt.ylabel("amplitude") plt.title(f"Voltage waveform for different frequencies") plt.show()
方案一:调整类职责,让参数类直接处理电压计算
将公共参数(频率、振幅、颜色)封装在一个类中,同时添加接收时间t的电压计算方法,避免重复实例化子类:
import math from matplotlib import pyplot as plt class WaveformParams: def __init__(self, f, a): self.freq = f self.ampl = a self.color = (f/a/3, (f/a)/2, (f/a)) self.omega = 2 * math.pi * f # 提前计算角频率,减少重复计算 def calc_volt(self, t): return self.ampl * math.sin(self.omega * t) if __name__ == '__main__': for (f,a) in [(0.05,1.5), (0.1,1)]: waveform = WaveformParams(f, a) time = list(range(50)) # 复用同一个参数实例计算所有时间点的电压 voltages = [waveform.calc_volt(t) for t in time] plt.plot(time, voltages, color=waveform.color) plt.xlabel("time") plt.ylabel("amplitude") plt.title("Voltage waveform for different frequencies") plt.show()
优化点:
- 每组
(f,a)仅实例化一次WaveformParams,避免重复初始化频率、振幅和颜色 - 提前计算角频率
omega,减少循环内的重复计算 - 直接调用参数实例的方法计算电压,无需创建大量临时对象
方案二:使用组合而非继承,传递参数实例
如果坚持保留类的分层结构,可通过组合方式让子类持有参数实例,而非继承:
import math from matplotlib import pyplot as plt class WaveformParams: def __init__(self, f, a): self.freq = f self.ampl = a self.color = (f/a/3, (f/a)/2, (f/a)) self.omega = 2 * math.pi * f class VoltageCalculator: def __init__(self, t, params): self.time = t self.params = params def volt(self): return self.params.ampl * math.sin(self.params.omega * self.time) if __name__ == '__main__': for (f,a) in [(0.05,1.5), (0.1,1)]: params = WaveformParams(f, a) time = list(range(50)) voltages = [VoltageCalculator(t, params).volt() for t in time] plt.plot(time, voltages, color=params.color) plt.xlabel("time") plt.ylabel("amplitude") plt.title("Voltage waveform for different frequencies") plt.show()
优化点:
- 每组
(f,a)仅创建一次WaveformParams实例,内部循环仅传递该实例给计算类 - 继承关系改为组合,职责更清晰:
WaveformParams管理参数,VoltageCalculator负责单时间点的电压计算
内容的提问来源于stack exchange,提问作者Leon Chang
相关产品推荐
相关产品推荐

