Python: Введение в ООП
Теория: Свойства
Представим, что у нас есть такой класс:
Что нам делать, если мы захотим иметь возможность получить еще и полное имя (имя+фамилию) объекта?
Мы могли бы в инициализаторе добавить строчку self.full_name = name + ' ' + surname. Но если впоследствии имя или фамилия поменяются, полное имя устареет, и его нужно будет не забыть поменять.
Также мы могли бы добавить метод с именем вроде get_full_name, который бы возвращал полное имя. Но и такой вариант не идеален, ведь нам хочется работать с полным именем, как с простым атрибутом-переменной.
Оказывается, что в Python есть средство, позволяющее получить атрибут, значение которого вычисляется динамически, то есть во время обращения к атрибуту. Речь идет о свойствах.
Добавим в класс свойство и посмотрим на его использование:
full_name выглядит как утка, то есть как атрибут. Но вычисляется динамически. И если мы поменяем name, то full_name также изменится:
Как вы можете видеть, свойство объявляется как метод без параметров (кроме self, естественно), декорированный с помощью property. Такой метод, возвращающий динамически вычисляемое значение, называется геттером (getter).
Сеттер
Атрибутам пространства имен можно присваивать значения, но что делать, если атрибут — свойство? Если вы попытаетесь присвоить значение свойству, у которого один лишь getter, вы получите ошибку "AttributeError: can't set attribute".
Чтобы иметь возможность присвоить значение свойству, нужно использовать сеттер (setter). Сеттер — это тоже метод, который принимает новое значение для атрибута и как-то его обрабатывает. Чтобы метод стал сеттером, его тоже нужно соответствующим образом декорировать. Если у вас уже есть геттер, вы можете сделать так:
Теперь свойству full_name можно присваивать новое полное имя. В итоге оно будет разделено по пробелу на две части, первая из которых станет новым именем, а вторая — фамилией. Пример:
Сеттеры часто используют для того, чтобы проверить корректность нового значения или произвести какие-то его преобразования перед фактическим сохранением в другие атрибуты.
Делитер
Кроме геттеров и сеттеров, в Python существует еще один важный метод для управления атрибутами классов — это делитеры (deleter). Этот метод предоставляет дополнительный уровень контроля над тем, как атрибуты класса удаляются.
Делитер — это особый метод в классе, который вызывается при удалении атрибута. Как правило, удаление атрибута - это нечастая операция, и в большинстве случаев мы можем обойтись без явного определения делитера. Тем не менее, зная о его существовании, мы можем контролировать процесс удаления атрибутов, например, очищать связанные ресурсы или выполнять некоторую логику очистки.
В нашем примере с классом Person, если мы решим реализовать делитер для свойства full_name, то его можно использовать для удаления имени и фамилии. Давайте посмотрим, как это работает:
Теперь при удалении свойства full_name будет вызываться наш делитер, который устанавливает свойствам name и surname значение None, тем самым "удаляя" эти значения. Пример:
Использование делитера особенно полезно в случаях, когда необходимо управлять удалением важных или связанных данных, или выполнять освобождение ресурсов (как, например, закрытие файлов или сетевых соединений) в момент уничтожения объекта или его свойств.
Декоратор property
Если посмотреть в документацию к декоратору property, то можно увидеть такую сигнатуру:
Первые три аргумента позволяют задать getter, setter и deleter, а аргумент doc позволяет указать docstring. В такой форме property удобно использовать, когда вы уже имеете готовые функции, которые хотите просто "упаковать" в свойство:
Также обычный вызов property может пригодиться, если вы будете делать свои декораторы, реализующие какие-то особенные свойства.

.png)


