Python: 实现不同类型的基础 class

Python: Implement base class for different types

我想知道是否有办法为不同的类型实现基础 class 的子classes。每个 subclass 应该有单独的输入和输出类型,同时提供与基础 class.

相同的行为

背景:我想处理电压和温度样本。 100 个电压样本构成一个 VoltageDataset。 100 个温度样本组成一个 TemperatureDataset。多个 VoltageDatasets 形成一个 VoltageDataCluster。温度也一样。数据集的处理取决于它们的物理量。为确保电压相关处理不能应用于温度样本,我想添加类型提示。

所以,如果有一种方法可以定义 VoltageDataClustes 方法 append_dataset 只允许将 VoltageDataset 作为输入类型,我会很高兴。温度相同。

有没有一种无需复制和粘贴即可实现此行为的方法?

# base class
class DataCluster:
    def __init__(self, name):
        self.name = name
        self.datasets = list()

    def append_dataset(self, dataset: Dataset) -> None:
        self.datasets.append(dataset)

# subclass that should allow VoltageDataset input only.
class VoltageDataCluster(DataCluster):
    pass

# subclass that should allow TemperatureDataset input only.
class TemperatureDataCluster(DataCluster):
    pass

谢谢! 尼克拉斯

你可以使用 pydantic generic models.

from typing import Generic, TypeVar, List
from pydantic.generics import GenericModel

DataT = TypeVar('DataT')

class DataCluster(GenericModel, Generic[DataT]):
    name: str
    datasets: List[DataT] = []

    def append_dataset(self, dataset: DataT) -> None:
        self.datasets.append(dataset)

voltage_cluster = DataCluster[VoltageDataset](name="name")
voltage_cluster.append_dataset(some_voltage_dataset)

当您继承 class 时,它会自动继承 class 的功能,因此无需复制和粘贴。我将用一个例子来说明这一点。

# DataCluster.py
class DataCluster:
  def __init__(self, name):
    self.name = name

  def printHello(self):
    print("Hello")
  # This will work in sub classes that have a "data" attribute
  def printData(self):
    print(self.data)


# VoltageDataCluster.py
from superclasses.DataCluster import DataCluster
class VoltageDataCluster(DataCluster):

  def __init__(self, differentInput):
    self.differentInput = differentInput
    self.data = "someotherdata"


# mainclass.py
from superclasses.DataCluster import DataCluster
from superclasses.VoltageDataCluster import VoltageDataCluster

try:
  dc = DataCluster("mark")
  dc.printHello();

  # The input for this class is not name
  vdc = VoltageDataCluster("Some Other Input")

  # These methods are only defined in DataCluster
  vdc.printHello()
  vdc.printData()

如您所见,尽管我们只在超级 class 中定义了“printHello”方法,但另一个 class 在使用不同的输入时继承了该方法。所以不需要复制和粘贴。 Here is a runnable example(我添加了注释以告诉您在哪里可以找到每个使用的文件)。

编辑:添加了数据属性,因此它与您的示例更相关。