Прочитав эту главу в «Expert Python Programming» – Расширенные модели доступа доступа ATTRBIUTE – https://subscription.packtpub.com/book/aplication_development/9781789808896/4/CH04LVL1SEC39/advanced-attribute-access-patterns решил реализовать @property частично. Вот окончательный результат – https://gist.github.com/mzsrtgzr2/46975900b8d7a8e6f8cc51d1a40ca940.
class myproperty: def __init__(self, func): self.f = func def setter(self, func): self.setter_func = func return self # (1) why do we need this? read below on def __get__(self, instance, klass): return self.f(instance or klass) def __set__(self, instance, value): self.setter_func(instance, value) class Foo: def __init__(self): self._val=0 @myproperty def temperature(self): return self._val @temperature.setter def temperature(self, value): # (2) why need same name as getter? print('setting to', value) self._val = value ins = Foo() print(int.temperature) # 0 ins.temperature = 6 print(int.temperature) # 6
Важно понимать, как работают декораторы. Это ключ, чтобы понять этот код. украшены Функция заменяется экземпляром вашего декоратора (или функции в случае, если вы используете функцию декоратора и не класс). Что говорят, вы можете добавить функциональные возможности к вашему декоратору, как __get__
и __set__
, как в коде выше. __get__
– Делая операция «чтение» на классе декоратора. __set__
– Делая операция «Написать» на классе декоратора.
Это еще один способ посмотреть на декораторы – его можно использовать для «дескрипторов данных» (при доступе к поле, как в ins.mperature
), а не только как функциональные обертки (реализованные с __Call__
, Как в ins.temperature ()
).
Важно – почему Оформленный набор метод
также следует назвать температура
?
Декоратор работает так:
@dec def func1: pass
фактически преобразуется
func1 = dec(func1)
Так что название функции важно.
Что произойдет, если мы не используем одно и то же имя в (2) или бросьте вернуть себя
Заявление в конце нашего декоратора: что раньше было температура
В нашем классе переопределяется на Нет
– Потеря все функциональности, которые мы думали, мы построили. У нас действительно случается:
class Foo: def __init__(self): self._val=0 def temperature(self): return self._val temperature = myproperty(temperature) # instantiating myproperty class def temperature(self, value): # (2) why need same name as getter? print('setting to', value) self._val = value temperature = temperature.setter(temperature)
В этом примере поле свойства температура
всегда Ссылочное имя
и не могу изменить это.
Оригинал: “https://dev.to/mzsrtgzr2/doing-python-s-property-myself-42e5”