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(我添加了注释以告诉您在哪里可以找到每个使用的文件)。
编辑:添加了数据属性,因此它与您的示例更相关。
我想知道是否有办法为不同的类型实现基础 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(我添加了注释以告诉您在哪里可以找到每个使用的文件)。
编辑:添加了数据属性,因此它与您的示例更相关。