Home > Back-end >  Returning a base class object from a function that supposes to return the derived class
Returning a base class object from a function that supposes to return the derived class

Time:12-08

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
  • Related