Intermediate Python
  • Introduction
  • Средства разработки
    • Виртуальное окружение
    • Отладка
    • Анализ объекта
  • Синтаксис
    • Исключения
    • for - else
    • Тернарные операторы
    • global и return
    • Функция open
    • *args и **kwargs
    • Менеджеры контекста
  • Функциональное программирование
    • enumerate
    • Анонимные функции
    • Структура данных set
    • map и filter
    • Абстракция списков
  • Структуры данных
    • Генераторы
    • Корутины
    • Классы
  • Типы данных
    • collections
    • Изменяемость
    • Магия __slots__
  • Декораторы
    • Что такое декоратор?
    • Кэширование функций
  • Разное
    • Однострочники
    • Python C расширения
    • Разработка под Python 2+3
Powered by GitBook
On this page
  • Python 3.2+
  • Python 2+
  1. Декораторы

Кэширование функций

Кэширование функций позволяет кэшировать возвращаемые значения функций в зависимости от аргументов. Это может помочь сэкономить время при работе с вводом/выводом на повторяющихся данных. До Python 3.2 мы должны были бы написать собственную реализацию. В Python 3.2+ появился декоратор lru_cache, который позволяет быстро кэшировать возвращаемые функцией значения.

Давайте посмотрим, как мы можем воспользоваться кэшированием в Python 3.2+ и в более старых версиях.

Python 3.2+

Реализуем функцию расчета n-ого числа Фибоначчи с использованием lru_cache:

from functools import lru_cache

@lru_cache(maxsize=32)
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

>>> print([fib(n) for n in range(10)])
# Вывод: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Аргумент maxsize сообщает lru_cache сколько последних значений запоминать.

Мы также можем легко очистить кэш:

fib.cache_clear()

Python 2+

В старых версиях языка также есть несколько путей достижения схожего эффекта. Вы можете сами реализовать любой тип кэширования. Это зависит только от ваших потребностей. Вот базовое решение:

from functools import wraps

def memoize(function):
    memo = {}
    @wraps(function)
    def wrapper(*args):
        try:
            return memo[args]
        except KeyError:
            rv = function(*args)
            memo[args] = rv
            return rv
    return wrapper

@memoize
def fibonacci(n):
    if n < 2: return n
    return fibonacci(n - 1) + fibonacci(n - 2)

fibonacci(25)

Примечание: memoize не сможет кэшировать типы данных, которые нельзя хешировать (словари, списки и т.д.). Только объекты неизменяемых типов подлежат кэшированию. Держите это в уме при использовании декоратора.

PreviousЧто такое декоратор?NextОднострочники

Last updated 6 years ago

от Caktus Group, в которой они рассказывают историю бага в Django, который появился из-за lru_cache. Рекомендую к ознакомлению.

Отличная статья