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”[attr-defined]
当我需要调用一个方法,但不是每个实现ICommand接口的类都有这个方法时,我该怎么做呢?
我尝试用#type ignore注解行,但我想知道处理这个问题的更好方法
2条答案
按热度按时间oyt4ldly1#
请看下面两行:
即使我们忽略你调用变量
ID_CHANGE_AIR_TEMPERATURE
的事实,它仍然意味着你知道comando
是ChangeTemperatureAirConditioner
类型,从你如何使用它(你在它上面调用.set_temperature(25)
)。一个解决方案是从
ICommand
到ChangeTemperatureAirConditioner
的cast
:osh3o9ms2#
遵循mypy指南:
如果您的代码太过神奇,我无法理解,您可以通过显式地赋予变量或参数Any类型来使其动态类型化
来源:https://mypy.readthedocs.io/en/stable/dynamic_typing.html
解决这个问题的最好方法是将
Aplicativo
类中的get_command
方法更改为:解决我的问题