我们可以让父类的初始化次数少于子类的初始化次数吗?

问题描述 投票:0回答:3

我尝试使用类继承来绘制具有不同频率 (

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)) # some random RGB numbers

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()

它有效。但对于

Child(x, f, a)
的每个实例化,它也会运行
super().__init__
,这不会因每个变量
x
而改变。我想知道是否有一种方法可以在变量
Parent
的外循环中运行
f, a
并在变量
Child
的内循环中运行
x

python class inheritance
3个回答
1
投票

我认为没有充分的理由在这里使用像

Parent
Child
这样的类。这些类上的大多数属性都是设置但不读取的,并且不需要多次读取任何属性。重新考虑您是否真的需要这些课程。

我建议的代码是--

import math
from matplotlib import pyplot as plt

def make_color(freq, ampl):
    return (freq / ampl / 3, freq / ampl / 2, freq / ampl)  # some random RGB numbers

def calc_volt(time, freq, ampl):
    omega = 2 * math.pi * freq
    return ampl * math.sin(omega * time)

if __name__ == "__main__":
    for freq, ampl in [(0.05, 1.5), (0.1, 1)]:
        color = make_color(freq, ampl)
        time = [i for i in range(50)]
        cl = [calc_volt(x, freq, ampl) for x in time]
        plt.plot(time, cl, color=color)

    plt.xlabel("time")
    plt.ylabel("amplitude")
    plt.title("Voltage waveform for different frequencies")
    plt.show()

我同意对于像这样的简单问题,你不需要上课。但我用它作为例子来探索不同的设计。

没关系。我们继续上课吧。

Parent.__init__
中最重的部分是
color
的计算,并且
color
从不用于
Child
的实例,因此计算被浪费了。我建议通过
functools.cached_property
让它变得懒惰。

相关部分可以改为---

from functools import cached_property

class Parent:
    def __init__(self, f, a):
        self.freq = f
        self.ampl = a

    @cached_property
    def color(self):
        return (f / a / 3, (f / a) / 2, (f / a))  # some random RGB numbers

0
投票

其实,有了类变量,我们就可以消除类继承部分:

import math
from matplotlib import  pyplot   as plt

class Parent:
    freq = None
    ampl = None
    color = None
    def __init__(self, f, a):
        Parent.freq = f
        Parent.ampl = a
        Parent.color = (f/a/3, (f/a)/2, (f/a))

class Child:
    def __init__(self, t):
        self.time = t
    def volt(self):
        omega = 2*math.pi*Parent.freq
        return Parent.ampl * math.sin(omega*self.time)

if  __name__ == '__main__':
    for (f,a) in [(0.05,1.5), (0.1,1)]: 
        Parent(f, a) 
        time = [i for i in range(50)]
        cl = [Child(x).volt() for x in time]    
        plt.plot(time, cl, color=Parent.color) 

    plt.xlabel("time")
    plt.ylabel("amplitude")
    plt.title(f"Voltage waveform for different frequencies")
    plt.show()

-1
投票

您可以为父类使用静态/类变量

import math
from matplotlib import pyplot as plt

class Parent:
    freq = None
    ampl = None

    def __init__(self):
        self.color = (self.freq/self.ampl/3, (self.freq/self.ampl)/2, (self.freq/self.ampl)) # some random RGB numbers

class Child(Parent):
    def __init__(self, t):
        self.time = t

    def volt(self):
        omega = 2 * math.pi * self.freq
        return self.ampl * math.sin(omega * self.time)

if __name__ == '__main__':
    for freq, ampl in [(0.05, 1.5), (0.1, 1)]:
        Parent.freq = freq
        Parent.ampl = ampl
        color = Parent().color
        time = [i for i in range(50)]
        cl = [Child(x).volt() for x in time]
        plt.plot(time, cl, color=color)

    plt.xlabel("time")
    plt.ylabel("amplitude")
    plt.title("Voltage waveform for different frequencies")
    plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.