允许稍后添加新 类 的最佳实践?
Best practice for allowing new classes to be added later?
我正在制作一个 python 程序来模拟简单的电子电路,我正在 kivy 中制作图形用户界面。允许我(或理论上其他人)添加程序将允许在电路构建中使用的新型组件(继承自基本组件 class)的最佳实践是什么?需要有一个 class 作为电路的一部分进行交互的方法和属性,以及一个 kivy 文件或其他表示如何在 gui 中显示的表示。
我的第一个想法是有一个组件文件夹,其中包含每个组件的单独文件夹,每个组件都有一个 python 文件用于 class 和一个 kivy 文件用于 gui 表示。但是,似乎没有一种根据文件名从文件导入的好方法,而且看起来很乱。我想这种事情在可扩展程序中很常见,所以一定有更好的方法来做到这一点。任何帮助将不胜感激。
这是一个示例,我使用 args
和 kwargs
使代码更加干练。我用所有其他人都可以继承的参数制作了一个单一的基础class。
所以所有组件都有阻力,因此您可以将其作为基础 class 中的参数,而不必在继承自它的其他 class 中重复它。
class Mammal(object):
def __init__(self, genus, species, agility, *extra_args, **extra_kwargs):
#extra is ignored as the subclasses handle them differently
self.species = species
self.genus = genus
self.agility = agility
def speak(self):
print("Generic {0} making generic {0} sounds".format(self.genus + " " + self.species))
class Human(Mammal):
def __init__(self, *args, **kwargs): #DRYer that re-listing the parameters
super().__init__(*args, **kwargs) #Call init of Mammal
self.intelligence = args[-1] #Uses args
class Hedgehog(Mammal):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.spikiness = kwargs["spikiness"] #Uses kwargs
stephen_hawking = Human("Homo", "Sapiens", 1, 100)
#100 is added to args and handled with self.intelligence = args[-1]
sanic = Hedgehog("Erinaceus", "Europaeus", (2 ** 63) - 1, spikiness = 10)
因此,对于人类,我添加了一个特定于人类 class 的额外参数,即智力。通过简单地向初始化添加另一个参数并在 Human.__init__
中处理它来添加它。
对于hedgehog,我添加了一个额外的关键字参数,通过获取键spikiness
的值来处理。这两者可以结合使用。如果我愿意,我可以创建一个添加了 spikiness
的 class PricklyMammal
并从中继承 Porcupine
、Hedgehog
和 Cactus
,所有这些都将具有 PricklyMammal
的默认参数和关键字参数:来自 Mammal
的参数和我添加到 PricklyMammal
的额外参数
我不知道您对此了解多少,如果其中有些内容有点傲慢,我深表歉意,但我希望这对您有所帮助!
P.S。没有冒犯,史蒂文霍金。我们爱你。
我过去也做过类似的事情。第一步是找出组件的共同点:
- 节点列表
- 函数
print_time_domain_analysis
接收用于时域分析的电导矩阵和 returns 使用组件参数更新的相同矩阵。
- 用于其他类型分析的类似函数,例如
print_frequency_domain_analysis
。
- 在您的情况下,一种在 GUI 上打印组件的方法。
您最终可能会得到如下内容:
from abc import ABC, abstractmethod
class TimeAnalysisComponent(ABC):
def __init__(self, nodes):
self.nodes = nodes
super().__init__()
@abstractmethod
def print_time_domain_analysis(
self,
conductance_matrix,
current_vector,
delta_t):
"""
Prints the component's parameters on a Conductance Matrix and on its
Current Vector for time domain analysis
"""
pass
@abstractmethod
def print_component_on_gui(self, gui_stuff):
"""
Prints component on GUI.
"""
pass
然后其他人就可以通过子类化 TimeAnalysisComponent 并实现其抽象方法来创建新组件。
我正在制作一个 python 程序来模拟简单的电子电路,我正在 kivy 中制作图形用户界面。允许我(或理论上其他人)添加程序将允许在电路构建中使用的新型组件(继承自基本组件 class)的最佳实践是什么?需要有一个 class 作为电路的一部分进行交互的方法和属性,以及一个 kivy 文件或其他表示如何在 gui 中显示的表示。
我的第一个想法是有一个组件文件夹,其中包含每个组件的单独文件夹,每个组件都有一个 python 文件用于 class 和一个 kivy 文件用于 gui 表示。但是,似乎没有一种根据文件名从文件导入的好方法,而且看起来很乱。我想这种事情在可扩展程序中很常见,所以一定有更好的方法来做到这一点。任何帮助将不胜感激。
这是一个示例,我使用 args
和 kwargs
使代码更加干练。我用所有其他人都可以继承的参数制作了一个单一的基础class。
所以所有组件都有阻力,因此您可以将其作为基础 class 中的参数,而不必在继承自它的其他 class 中重复它。
class Mammal(object):
def __init__(self, genus, species, agility, *extra_args, **extra_kwargs):
#extra is ignored as the subclasses handle them differently
self.species = species
self.genus = genus
self.agility = agility
def speak(self):
print("Generic {0} making generic {0} sounds".format(self.genus + " " + self.species))
class Human(Mammal):
def __init__(self, *args, **kwargs): #DRYer that re-listing the parameters
super().__init__(*args, **kwargs) #Call init of Mammal
self.intelligence = args[-1] #Uses args
class Hedgehog(Mammal):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.spikiness = kwargs["spikiness"] #Uses kwargs
stephen_hawking = Human("Homo", "Sapiens", 1, 100)
#100 is added to args and handled with self.intelligence = args[-1]
sanic = Hedgehog("Erinaceus", "Europaeus", (2 ** 63) - 1, spikiness = 10)
因此,对于人类,我添加了一个特定于人类 class 的额外参数,即智力。通过简单地向初始化添加另一个参数并在 Human.__init__
中处理它来添加它。
对于hedgehog,我添加了一个额外的关键字参数,通过获取键spikiness
的值来处理。这两者可以结合使用。如果我愿意,我可以创建一个添加了 spikiness
的 class PricklyMammal
并从中继承 Porcupine
、Hedgehog
和 Cactus
,所有这些都将具有 PricklyMammal
的默认参数和关键字参数:来自 Mammal
的参数和我添加到 PricklyMammal
我不知道您对此了解多少,如果其中有些内容有点傲慢,我深表歉意,但我希望这对您有所帮助!
P.S。没有冒犯,史蒂文霍金。我们爱你。
我过去也做过类似的事情。第一步是找出组件的共同点:
- 节点列表
- 函数
print_time_domain_analysis
接收用于时域分析的电导矩阵和 returns 使用组件参数更新的相同矩阵。 - 用于其他类型分析的类似函数,例如
print_frequency_domain_analysis
。 - 在您的情况下,一种在 GUI 上打印组件的方法。
您最终可能会得到如下内容:
from abc import ABC, abstractmethod
class TimeAnalysisComponent(ABC):
def __init__(self, nodes):
self.nodes = nodes
super().__init__()
@abstractmethod
def print_time_domain_analysis(
self,
conductance_matrix,
current_vector,
delta_t):
"""
Prints the component's parameters on a Conductance Matrix and on its
Current Vector for time domain analysis
"""
pass
@abstractmethod
def print_component_on_gui(self, gui_stuff):
"""
Prints component on GUI.
"""
pass
然后其他人就可以通过子类化 TimeAnalysisComponent 并实现其抽象方法来创建新组件。