Reputation: 13
I wonder if there is a way to implement subclasses of a base class for different types. Each subclass should have individual input and output types while providing same behaviour as the base class.
Background: I want to process voltage and temperature samples. 100 voltage samples form a VoltageDataset. 100 temperature samples form a TemperatureDataset. Multiple VoltageDatasets form a VoltageDataCluster. Same for temperature. The processing of Datasets depends on their physical quantity. To ensure that voltage related processing can't be applied to temperature samples I'd like to add type hints.
So I'd would be nice if there is a way to define that VoltageDataClustes method append_dataset allows VoltageDataset as input type only. Same for temperature.
Is there a way to implement this behaviour without copy&pasting?
# 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
Thanks! Niklas
Upvotes: 1
Views: 505
Reputation: 289
You could use 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)
Upvotes: 2
Reputation: 96
When you inherit a class it automatically inherits the functionality of the class so there is no need to copy and paste. I'll illustrate this with an example.
# 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()
As you can see, even though we only defined the "printHello" method in the super class, the other class inherited this method while using different inputs. So no copy and pasting required. Here is a runnable example (I added comments to tell you where to find each file used).
EDIT: Added a data attribute so its more relevant to your example.
Upvotes: 0