Как отключить functools @lru_cache при локальной разработке

Как отключить кеширование при работе с Python functools? У нас есть логическая настройка, позволяющая отключить кеш. Это для локальной работы.

Я подумал примерно так:

@lru_cache(disable=settings.development_mode)

Но такой настройки нет. Я что-то упускаю? Как люди это делают?

Люди делают это? lru_cache — это то, что, вероятно, не следует отключать, оно безоговорочно должно быть частью вашего кода. У вас могут быть другие виды кешей, такие как HTTP-заголовки и т. д., которые имеют разные настройки в производстве и разработке. Но это ваш собственный код бизнес-логики, а не что-то интегрированное в Python.

deceze 15.08.2024 16:04

@deceze Хорошо, я понимаю. Но как протестировать изменения во время разработки в функции, имеющей этот декоратор? После первого вызова функция больше не будет вызываться.

Kulu 15.08.2024 16:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
50
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете задать максимальный размер 0 (или отрицательный, если уж на то пошло), что фактически отключит кеш, поскольку никакие значения вообще не могут попасть в кеш.

import functools

@functools.lru_cache(maxsize=0)
def f(a):
    print("entered the function in f")

@functools.lru_cache
def g(a):
    print("entered the function in g")

f(1) 
f(1) # -> will also show "entered the function in f", thus not using the cache
g(1)
g(1) # -> does not show anything, thus using the cache

Для вашего примера это означает, что вы можете использовать переменную для установки размера, а когда вы хотите отключить ее, установите для этой переменной значение 0.

Вместо этого вы можете применить декоратор условно:

def f(x):
    return 2 * x

if not settings.development_mode:
    f = lru_cache(f)

lru_cache предоставляет несколько функций для кэшированной функции. Например. cache_info(), cache_clear() и __wrapped__()

Итак, здесь два варианта:

  1. очищать кеш после каждого выполнения
  2. вызвать базовую функцию напрямую, минуя lru_cache

import random


@lru_cache
def foo():
    return random.random()


def test_foo():

    foo()

    # Clear cache
    foo.cache_clear()
    # Call again
    foo()

    # Call underlying function, uncached
    foo.__wrapped__()    

cache_info() также может быть полезен для анализа состояния кэша. Например.

> foo.cache_info()
CacheInfo(hits=1, misses=1, maxsize=128, currsize=1)

Документы: https://docs.python.org/3/library/functools.html#functools.lru_cache

Ответ принят как подходящий

Если вы хотите условно отключить кеширование при использовании functools.lru_cache,, вам нужно сделать это вручную. Вам нужен декоратор, который может условно применять lru_cache на основе ваших настроек.

В качестве руководства я использую документацию docsOnFunctools

Цитаты из документов: Если для параметра maxsize установлено значение None, функция LRU отключена, и кеш может расти без ограничений. Если для параметра typed установлено значение true, аргументы функций разных типов будут кэшироваться отдельно. Если typed имеет значение false, реализация обычно будет рассматривать их как эквивалентные вызовы и кэшировать только один результат. (Некоторые типы, такие как str и int, могут кэшироваться отдельно, даже если типизировано значение false.)

from functools import lru_cache, wraps

def remove_lru_cache(maxsize=128, typed=False, enable_cache=True):
    def decorator(func):
        if enable_cache:
            return lru_cache(maxsize=maxsize, typed=typed)(func)
        return func
    return decorator

Затем вы можете применить его к своему коду

# settings
your_settings = {
    'dev_mode': True  #set False to enable caching
}
@remove_lru_cache(maxsize=None, typed=False, enable_cache=not settings['dev_mode'])
def add(nums: List[int]) -> int:
    return sum(nums)

Другие вопросы по теме