Вот и стало интересно.
Это пример моих экспериментов:
# бла-бла # Программа имитирует отношения пульта дистанционного # управления, телевизора, и переключателей каналов со звуком. from abc import ABCMeta, abstractmethod from enum import Enum class Observer: def __init__(self): self.__observer = None def set_observer(self, observer): self.__observer = observer def observer_notify(self): self.__observer.update(self) class Remote(Observer): def __init__(self): super().__init__() self.way_of_change = None self.changeable_property = None def reduces(self, a_property: "Property"): self.changeable_property = a_property self.way_of_change = WayOfChange.REDUCE print(a_property.value) self.observer_notify() def increases(self, a_property: "Property"): self.changeable_property = a_property self.way_of_change = WayOfChange.INCREASE self.observer_notify() class TV: def __init__(self): self.__properties = [] self.__switches = [] def update(self, remote: "Remote"): print(self.__class__.__name__, "принял оповещение от", remote.__class__.__name__) if not isinstance(remote, Remote): print("это не пульт") return for switch in self.switches__cl: if switch.controlled_property.equal( remote.changeable_property): if remote.way_of_change is WayOfChange.INCREASE: switch.increment_value() elif remote.way_of_change is WayOfChange.REDUCE: switch.decrement_value() else: pass @property def switches__cl(self): return self.__switches[:] def adds_switches(self, *switches: "Switch"): for switch in switches: if isinstance(switch, Switch): self.__switches.append(switch) def adds_new_properties(self, *properties: "PropertyOfTV"): for a_property in properties: if isinstance(a_property, PropertyOfTV): self.__properties.append(a_property) def watch(self): pass def turn_on(self): pass class WayOfChange(Enum): INCREASE = "+" REDUCE = "-" class Property(Enum): SOUND = "sound" CHANNELS = "channels" class PropertyOfTV(metaclass=ABCMeta): def __init__(self, a_property: "Property", *, max_value=10, min_value=0 ): self.__min_value = min_value self.__max_value = max_value self.__property = a_property self.__value = self.__min_value @property def value(self): return self.__value @value.setter def value(self, new_value): # Если изменения выходят за диапазон, то не вносятся if not self.__is_value_error(new_value): self.__value = new_value print("было изменено ", end="") elif self.max_value < new_value \ or new_value < self.min_value: print("не изменилось.") pass print("и равно теперь", self.value) @property def property_tv(self): return self.__property @property def min_value(self): return self.__min_value @property def max_value(self): return self.__max_value def equal(self, a_property: "Property"): if self.property_tv is a_property: return True else: return False def __is_value_error(self, new_value): if self.min_value > new_value < self.__max_value: return True else: return False class Switch(metaclass=ABCMeta): def __init__(self, controlled_property: "PropertyOfTV", *, change_step): self.__controlled_property = controlled_property self.__change_step = change_step @property def controlled_property(self): return self.__controlled_property @property def change_step(self): return self.__change_step def increment_value(self): new_value = \ self.controlled_property.value + self.change_step self.__change_controlled_property_value(new_value) def decrement_value(self): new_value = \ self.controlled_property.value - self.change_step self.__change_controlled_property_value(new_value) @abstractmethod def _interaction_with_limits_of_boundary_values(сам, new_value): pass def __change_controlled_property_value(self, new_value): print(self.__class__.__name__, "переключает", self.controlled_property.property_tv.value, "и оно", end="") if self.__is_value_in_the_admissible_range(new_value): self.controlled_property.value = new_value else: self._interaction_with_limits_of_boundary_values(new_value) def __is_value_in_the_admissible_range(self, num): if self.controlled_property.min_value \ <= num \ <= self.controlled_property.max_value: return True else: return False class LinearSwitcher(Switch): """При достижении крайних значений - останавливается""" def _interaction_with_limits_of_boundary_values(self, new_value): if new_value > self.controlled_property.max_value: self.controlled_property.value = \ self.controlled_property.max_value elif new_value < self.controlled_property.min_value: self.controlled_property.value = \ self.controlled_property.min_value else: print("Но оно не изменилось.") class CircleSwitcher(Switch): """При достижении крайнего значения, переключается на противоположное.""" def _interaction_with_limits_of_boundary_values(self, new_value): if new_value > self.controlled_property.max_value: normalized_value = \ self.__normalizes_value( self.controlled_property.max_value ) self.controlled_property.value = \ new_value - normalized_value elif new_value < self.controlled_property.min_value: normalized_value = \ self.__normalizes_value(new_value) self.controlled_property.value = \ self.controlled_property.max_value - \ normalized_value def __normalizes_value(self, num_for_normalize): normalized_value = \ num_for_normalize - self.controlled_property.min_value return normalized_value if __name__ == "__main__": def testing(): print("Тестовая программа запущена.") property1 = PropertyOfTV( Property.CHANNELS, max_value=50, min_value=20, ) property2 = PropertyOfTV( Property.SOUND, max_value=10, min_value=0, ) tv = TV() tv.adds_new_properties(property1, property2) tv.adds_switches( LinearSwitcher(property2, change_step=1), CircleSwitcher(property1, change_step=1) ) remote = Remote() remote.set_observer(tv) def to_increase(a_property, val): for _ in range(val): print("Кто-то нажал на кнопку увеличивая", a_property.value) remote.increases(a_property) def to_decrease(a_property, val): for _ in range(val): print("Кто-то нажал на кнопку увеличивая", a_property.value) remote.reduces(a_property) to_increase(Property.SOUND, 12) to_decrease(Property.SOUND, 15) to_increase(Property.CHANNELS, 40) to_decrease(Property.CHANNELS, 50) testing()
Если я “не там искал”, то подскажите, пожалуйста, где они есть и можно поизучать.
ПС: спецом перевёл на инглишь, а то опять закроете, и поговорить не дадите.