0Pricing
Python Academy · Aula

functools: lru_cache e cached_property

Armazene em cache cálculos dispendiosos com lru_cache e cached_property.

functools: lru_cache e cached_property é uma aula grátis de Python Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Python Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Python Academy inclui 4 aulas no total.

O que é memoização?

A memoização armazena em cache o resultado de uma chamada de função, indexado por seus argumentos. Chamadas repetidas com os mesmos argumentos retornam instantaneamente o resultado armazenado.

def slow_fib(n):
    if n < 2: return n
    return slow_fib(n-1) + slow_fib(n-2)

# slow_fib(35) makes ~29 million calls
# With caching it makes only 35

@lru_cache

@functools.lru_cache(maxsize=128) armazena em cache até maxsize resultados recentes. Defina maxsize=None para obter um cache sem limite.

import functools

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

print(fib(50))  # instant

@cache — Python 3.9+

functools.cache é uma forma abreviada de lru_cache(maxsize=None) — um cache sem limite e com um nome mais simples.

import functools

@functools.cache
def factorial(n):
    return n * factorial(n-1) if n else 1

print(factorial(10))  # 3628800

Informações e limpeza do cache

Funções armazenadas em cache expõem .cache_info() (acertos, falhas e tamanho) e .cache_clear().

import functools

@functools.lru_cache(maxsize=100)
def square(n):
    return n * n

for i in range(5): square(i % 3)
print(square.cache_info())
# CacheInfo(hits=2, misses=3, maxsize=100, currsize=3)
square.cache_clear()

Política de remoção LRU

LRU (menos usado recentemente) remove o item que foi acessado há mais tempo quando o cache está cheio.

import functools

@functools.lru_cache(maxsize=3)
def compute(n):
    print(f"computing {n}")
    return n**2

for x in [1,2,3,4,1]:   # 4 evicts 1 (LRU), then 1 re-computes
    compute(x)

Somente argumentos hashable

lru_cache exige que todos os argumentos sejam hashable. Listas e dicionários não são hashable; use tuplas.

import functools

@functools.lru_cache(maxsize=None)
def sum_tuple(t):  # tuple is hashable
    return sum(t)

print(sum_tuple((1,2,3)))  # 6
# sum_tuple([1,2,3])  # TypeError

@cached_property

functools.cached_property calcula uma propriedade uma vez e armazena o resultado na instância, substituindo o descritor pelo valor.

import functools

class Circle:
    def __init__(self, r):
        self.r = r

    @functools.cached_property
    def area(self):
        import math
        print("computing...")
        return math.pi * self.r ** 2

c = Circle(5)
print(c.area)   # computing...  78.53...
print(c.area)   # 78.53... (cached, no print)

cached_property versus property

@property recalcula o valor a cada acesso. @cached_property calcula uma vez e armazena o resultado em instance.__dict__.

import functools

class Expensive:
    @property
    def always(self):    # runs every access
        return sum(range(1_000_000))

    @functools.cached_property
    def once(self):      # runs only first access
        return sum(range(1_000_000))

Segurança de threads em cached_property

cached_property não é segura para threads. Se várias threads a acessarem simultaneamente, o cálculo poderá ser executado mais de uma vez. Use um lock se necessário.

import functools, threading

class SafeCache:
    _lock = threading.Lock()

    @functools.cached_property
    def data(self):
        with self._lock:
            return expensive_computation()

Invalidando cached_property

Exclua o atributo da instância para invalidar o cache e forçar o recálculo no próximo acesso.

import functools

class Report:
    @functools.cached_property
    def summary(self):
        return compute_summary()

r = Report()
_ = r.summary      # computed
del r.summary      # invalidate
_ = r.summary      # recomputed

Usando lru_cache como cache de API

Armazene em cache as respostas da API durante uma sessão para evitar chamadas de rede redundantes. Limpe o cache quando dados atualizados forem necessários.

import functools, urllib.request, json

@functools.lru_cache(maxsize=32)
def get_user(user_id):
    url = f"https://api.example.com/users/{user_id}"
    with urllib.request.urlopen(url) as r:
        return json.loads(r.read())

user = get_user(42)   # network call
user = get_user(42)   # cached

Verificação rápida

Qual método limpa todos os resultados armazenados em cache de uma função decorada com @lru_cache?

Recapitulação

@lru_cache armazena resultados de funções em cache, indexados pelos argumentos (que devem ser hashable). @cache é um alias sem limite. @cached_property armazena em cache o cálculo de uma propriedade por instância. Inspecione com cache_info() e redefina com cache_clear().

Perguntas Frequentes

A aula “functools: lru_cache e cached_property” é grátis?

Sim — o texto completo de “functools: lru_cache e cached_property” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Python Academy, atualize para CoddyKit PRO. O curso de Python Academy inclui 4 aulas no total.

O que vou aprender em “functools: lru_cache e cached_property”?

Armazene em cache cálculos dispendiosos com lru_cache e cached_property. Você pratica Python Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Python Academy?

Nenhuma experiência prévia é necessária. Python Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “functools: lru_cache e cached_property”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Python Academy?

Sim. Cada aula de Python Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. itertools: iteradores infinitos e finitos
  2. itertools: combinatória
  3. functools: partial e reduce
  4. functools: lru_cache e cached_property
← Voltar para Python Academy