functools.cached_property()

@functools.cached_property(func)

Преобразует метод класса в свойство, значение которого вычисляется один раз, а затем кэшируется как обычный атрибут на время существования экземпляра. Аналогично property () (декоратор @property) с добавлением кеширования. Полезно для дорогостоящих вычисляемых свойств экземпляров, которые в противном случае фактически неизменяемы.

Пример:

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)

Механизм cached_property () несколько отличается от property (). Обычный атрибут блоков свойств записывает, если не определен установщик. Напротив, cached_property разрешает запись.

Декоратор cached_property запускается только при поиске и только тогда, когда атрибут с таким же именем не существует. Когда он запускается, cached_property записывает в атрибут с тем же именем. Последующее чтение и запись атрибута имеет приоритет над методом cached_property и работает как обычный атрибут.

Кешированное значение можно очистить, удалив атрибут. Это позволяет снова запустить метод cached_property.

Обратите внимание, что этот декоратор мешает работе словарей совместного использования ключей PEP 412. Это означает, что словари экземпляров могут занимать больше места, чем обычно.

Кроме того, этот декоратор требует, чтобы атрибут __dict__ в каждом экземпляре был изменяемым отображением. Это означает, что он не будет работать с некоторыми типами, такими как метаклассы (поскольку атрибуты __dict__ в экземплярах типов являются прокси только для чтения для пространства имен классов), и те, которые указывают __slots__ без включения __dict__ в качестве одного из определенных слотов (как такие классы вообще не предоставляют атрибут __dict__).

Если изменяемое сопоставление недоступно или если требуется совместное использование ключей с эффективным использованием пространства, эффект, аналогичный cached_property (), может быть достигнут с помощью стекирования property() поверх cache ():

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)

Новое в версии 3.8.

Last updated