Дескрипторы в Python позволяют контролировать, что происходит при чтении, изменении или удалении атрибута объекта. В руководстве подробно рассказывается, как использовать их для создания трех типов управляемых атрибутов: валидируемых, вычисляемых и загружаемых по требованию. В качестве примера используется вымышленное приложение для туризма в Японии.
Дескриптор — это класс, реализующий такие методы, как __get__, __set__ или __delete__, которые определяют поведение атрибута. Не все они обязательны. Метод __set_name__, появившийся в Python 3.6, сообщает дескриптору имя атрибута, с которым он связан, что позволяет хранить значение в __dict__ родительского объекта без конфликта имен. По словам автора, этот подход позволяет избежать загромождения кода декораторами @property, геттерами и сеттерами.
Валидируемые, вычисляемые и ленивые атрибуты
Первый пример, названный ValidatedRating, проверяет, что оценка является числом (целым или десятичным) в диапазоне между минимальным и максимальным значением, по умолчанию установленными в 1.0 и 5.0. При нечисловом значении возникает TypeError; если значение выходит за пределы диапазона — ValueError.
Второй пример, ComputedUSDPrice, служит для отображения в долларах США цены, хранящейся в японских иенах (JPY). Он вычисляет конвертацию на лету, используя курс обмена 0.0067, указанный в коде как приблизительный. Поскольку атрибут предназначен только для чтения, любая попытка записи вызывает AttributeError.
Третий пример, LazyItinerary, применяется к данным, затратным для получения, таким как чтение большого JSON-файла или запрос к базе данных расписания Синкансэна, японских высокоскоростных поездов. Дескриптор вычисляет значение только при первом обращении, помещает его в __dict__ экземпляра, а затем удаляется. Последующие обращения читают это значение напрямую. В примере включена имитация задержки в одну секунду.
Практическое применение на примере посещения Киото
Эти три дескриптора объединены в классе JapanTour. При инициализации с пунктом назначения «Киото», ценой 45000 JPY и оценкой 4.8 валидация запускается немедленно. Когда автор затем пытается присвоить оценке значение 6.0, перехватывается исключение и выводится сообщение «rating must be between 1.0 and 5.0.».
Первое обращение к маршруту выводит сообщение о симуляции запроса, а затем трехдневную программу: прибытие и регистрация в Киото, экскурсия по храмам и дегустация уличной еды, затем отъезд на Синкансэне. При втором обращении сообщение больше не появляется: значение читается напрямую из экземпляра.
В статье делается вывод, что эти три типа дескрипторов повышают надежность атрибутов класса, обеспечивая, соответственно, целостность данных, вычисление производных значений и управление затратными операциями.





