Форум сайта python.su
Хотел поискать примеры, но не нашёл в таком стиле.
Вот и стало интересно.
Это пример моих экспериментов:
# бла-бла # Программа имитирует отношения пульта дистанционного # управления, телевизора, и переключателей каналов со звуком. 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()
Отредактировано Nab (Март 14, 2016 13:40:09)
Офлайн
Много всего и поэтому непонятно, что конкретно из всего кода вы подразумеваете под стилем.
Может быть, обильное использование псевдоприватных переменных и методов? Ну и зачем? Какую задачу вы этим решаете? Или вы думаете, что понаделав бессмысленных пропертей, которые не делают ничего, кроме как задают и возвращают значение “приватного” атрибута, вы сделали программу лучше?
Ну и да, вот этот вот “стиль” сильно попахивает говнокодом
if self.controlled_property.min_value \ <= num \ <= self.controlled_property.max_value: return True else: return False
Отредактировано FishHook (Март 14, 2016 13:42:37)
Офлайн
Видимо, особым стилем здесь является отсутствие пустых строк там, где они традиционно ставятся.
Офлайн
fireSparrow
Это форумный движок их выпиливает, ТС не виноват.
Офлайн
Тогда извиняюсь, не знал про эту особенность.
Офлайн
FishHookБессмысленных там нет.
понаделав бессмысленных пропертей, которые не делают ничего, кроме как задают и возвращают значение “приватного” атрибута,
Какую задачу вы этим решаете?Решаю на питоне задачу соблюдения ооп-стиля, поидеальнее.
Ну и да, вот этот вот “стиль” сильно попахивает говнокодоммне самому эти переносы ненравятся ужасно, но это недостаток питона - без двух паралельно открытых окон программировать сложно. Приходится соблюдать ширину в 80 символов, а точечные нотации бывают длинными.
Отредактировано Nab (Март 14, 2016 15:06:43)
Офлайн
NabДа ты чо? Ну и какой великий смысл в этих строках кода?
Бессмысленных там нет.
@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
NabВы про инкапсуляцию что-ли? Ну и какую по-вашему задачу решает инкапсуляция и как вы её достигаете своим “стилем”?
Но да, принцип “открытости-закрытости” соблюдается, тут вы правы.
NabНет, вы решаете задачу переноса ООП-стиля из Джавы в питон, не понимая, что эти языки исповедуют принципиально разный подход к программированию. Забыли дзен питона?
Решаю на питоне задачу соблюдения ооп-стиля, поидеальнее.
Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
NabКакие нафиг переносы?
мне самому эти переносы ненравятся ужасно
return self.controlled_property.min_value <= num <= self.controlled_property.max_value
Nabахинея какая-то
без двух паралельно открытых окон программировать сложно
Отредактировано FishHook (Март 14, 2016 15:26:25)
Офлайн
return self.controlled_property.min_value \ <= num \ <= self.controlled_property.max_value
Отредактировано Shaman (Март 14, 2016 15:29:00)
Офлайн
В Вашем случае там вообще можно писать :
return self.controlled_property.min_value <= num <= self.controlled_property.max_value
Отредактировано ayb (Март 14, 2016 15:29:54)
Офлайн
return self.controlled_property.min_value <= num <= self.controlled_property.max_value
Офлайн