Как с помощью дескрипторов реализовать кастомный ленивый аналог декоратора @property?

Ленивое свойство можно реализовать non-data descriptor: при первом чтении вычислить значение и записать его в instance.__dict__. Дальнейшее чтение найдёт сохранённый атрибут без повторного вычисления.

Короткий ответ

Что ответить на собеседовании

Ленивое свойство можно реализовать non-data descriptor: при первом чтении вычислить значение и записать его в instance.dict. Дальнейшее чтение найдёт сохранённый атрибут без повторного вычисления.

Подробный разбор

Ответ с пояснениями

Ленивое свойство можно реализовать non-data descriptor: при первом чтении вычислить значение и записать его в instance.dict. Дальнейшее чтение найдёт сохранённый атрибут без повторного вычисления.

Пример для объектов с обычным dict:

class lazy_property:
    def __init__(self, func):
        self.func = func

    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, instance, owner=None):
        if instance is None:
            return self
        value = self.func(instance)
        instance.__dict__[self.name] = value
        return value

Использование: @lazy_property над методом без аргументов, кроме self. Здесь намеренно нет set, иначе приоритет дескриптора изменится. Удаление атрибута сбрасывает кеш. Такая простая реализация не гарантирует единственное вычисление при конкурентном доступе и не подходит объектам без dict.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее