I have a question about the correct architecture for base and derived classes.
Suppose a base class of some device and derived classes of specific devices. Some manager has a list of specific devices and a method to return any device by its name - see the implementation below.
Pycharm - rightfully - marks a problem, that expected type SpecificDevice, got BaseDevice instead
. This is true - while the method supposes to return a specific device, actually, it returns the base.
But how can I achieve my goal without breaking the rules of polymorphism?
class DeviceBase:
def __init__(self, name: str):
self.name: str = name
def turn_off(self):
pass
class DeviceLights(DeviceBase):
def dim_light(self):
pass
class DeviceOvens(DeviceBase):
def set_temperature(self):
pass
class Manager:
def __init__(self):
self._devices = [DeviceLights(name='corridor_light'), DeviceOvens(name='upper_oven')]
def _get_device_by_name(self, name: str) -> DeviceBase:
for device in self._devices:
if device.name == name:
return device
return DeviceBase(name='basic_device')
def get_light(self, name: str) -> DeviceLights:
return self._get_device_by_name(name=name) # Expected type 'DeviceLights', got 'DeviceBase' instead
def get_oven(self, name: str) -> DeviceOvens:
return self._get_device_by_name(name=name) # Expected type 'DeviceOvens', got 'DeviceBase' instead
CodePudding user response:
Consider using TypeVar
in typing
.
https://docs.python.org/3/library/typing.html#typing.TypeVar
from typing import TypeVar
DeviceBaseType = TypeVar('DeviceBaseType', bound='DeviceBase')
def _get_device_by_name(self, name: str) -> DeviceBaseType:
pass