mypy 不识别类的方法

问题描述 投票:0回答:1
from abc import ABC, abstractmethod
from typing import List


class AirConditioner:
    """Class that represents an air conditioner"""

    def __init__(self, identify: str, state: bool, temperature: int):
        self.identify = identify
        self._state = state
        self._temperature = temperature

    def turn_on(self) -> None:
        self._state = True

    def turn_off(self) -> None:
        self._state = False

    def set_temperature(self, temperature: int) -> None:
        self._temperature = temperature

    def get_state(self) -> bool:
        return self._state

    def get_temperature(self) -> int:
        return self._temperature


class ICommand(ABC):
    """Interface that represents a command"""

    @abstractmethod
    def execute(self) -> None:
        pass

    @abstractmethod
    def undo(self) -> None:
        pass


class TurnOnAirConditioner(ICommand):
    """Class that represents a command to turn on an air conditioner"""

    def __init__(self, air_conditioner: AirConditioner):
        self._air_conditioner = air_conditioner

    def execute(self) -> None:
        self._air_conditioner.turn_on()

    def undo(self) -> None:
        self._air_conditioner.turn_off()


class ChangeTemperatureAirConditioner(ICommand):
    """Class that represents a command to change the temperature of an air conditioner"""

    def __init__(self, air_conditioner: AirConditioner):
        self._air_conditioner = air_conditioner
        self._temperature = air_conditioner.get_temperature()
        self._temperature_anterior = self._temperature

    def set_temperature(self, temperature: int) -> None:
        self._temperature_anterior = self._temperature
        self._temperature = temperature

    def execute(self) -> None:
        self._air_conditioner.set_temperature(self._temperature)

    def undo(self) -> None:
        self._air_conditioner.set_temperature(self._temperature_anterior)


class Aplicativo:
    """Class that represents an application that uses the command pattern to control an air conditioner"""

    def __init__(self) -> None:
        self._comandos: List[ICommand] = []

    def set_comando(self, comando_app: ICommand) -> int:
        self._comandos.append(comando_app)
        return len(self._comandos) - 1

    def get_command(self, comando_id: int) -> ICommand:
        return self._comandos[comando_id]

    def pressing_button(self, comando_id: int) -> None:
        self._comandos[comando_id].execute()


if __name__ == "__main__":
    app = Aplicativo()

    my_air_conditioner = AirConditioner("Air Conditioner", False, 26)

    change_temperature_air = ChangeTemperatureAirConditioner(my_air_conditioner)
    turn_on_ar = TurnOnAirConditioner(my_air_conditioner)

    ID_TURN_AIR_ON = app.set_comando(turn_on_ar)
    ID_CHANGE_AIR_TEMPERATURE = app.set_comando(change_temperature_air)

    app.pressing_button(ID_TURN_AIR_ON)
    comando = app.get_command(ID_CHANGE_AIR_TEMPERATURE)
    comando.set_temperature(25)

当我运行上面的代码时,mypy 给我带来以下警告:

错误:“ICommand”没有属性“set_temperature”[属性定义]

需要调用一个方法,但不是每个实现了ICommand接口的类都有这个方法怎么办?

我尝试用#type ignore 注释行,但我想知道一个更好的方法来处理这个问题

python python-3.x mypy command-pattern
1个回答
0
投票

遵循 mypy 指南:

如果你的代码太神奇以至于 mypy 无法理解,你 可以使变量或参数动态类型化 给它 Any

类型

来源:https://mypy.readthedocs.io/en/stable/dynamic_typing.html

解决这个问题的最好方法是改变

get_command
方法,在
Aplicativo
类中:

from abc import ABC, abstractmethod
from typing import List, Any
    
    ...

class Aplicativo:
        """Class that represents an application that uses the command pattern to control an air conditioner"""
    
        ...

        def get_command(self, comando_id: int) -> Any:
            return self._comandos[comando_id]

        ...

用mypy解决问题

© www.soinside.com 2019 - 2024. All rights reserved.