functools: lru_cache y cached_property
Almacene en caché cálculos costosos con lru_cache y cached_property.
functools: lru_cache y cached_property es una lección gratuita de Python Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Python Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Python Academy incluye 4 lecciones en total.
¿Qué es la memoización?
La memoización almacena en caché el resultado de una llamada a una función, identificado por sus argumentos. Las llamadas repetidas con los mismos argumentos devuelven el resultado almacenado al instante.
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) almacena en caché hasta maxsize resultados recientes. Establezca maxsize=None para una caché sin límite.
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 es una forma abreviada de lru_cache(maxsize=None): una caché sin límite y con un nombre más claro.
import functools
@functools.cache
def factorial(n):
return n * factorial(n-1) if n else 1
print(factorial(10)) # 3628800Información y borrado de la caché
Las funciones con caché exponen .cache_info() (aciertos, fallos y tamaño) y .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 desalojo LRU
LRU (Least Recently Used, menos recientemente utilizado) desaloja el elemento al que se accedió hace más tiempo cuando la caché está llena.
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)Solo argumentos hashables
lru_cache requiere que todos los argumentos sean hashables. Las listas y los diccionarios no lo son; use tuplas en su lugar.
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 una propiedad una vez y almacena el resultado en la instancia, reemplazando el descriptor por el 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 frente a property
@property recalcula el valor en cada acceso. @cached_property lo calcula una vez y almacena el resultado en 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))Seguridad de subprocesos de cached_property
cached_property no es segura para subprocesos. Si varios subprocesos acceden a ella simultáneamente, el cálculo puede ejecutarse más de una vez. Use un bloqueo si es necesario.
import functools, threading
class SafeCache:
_lock = threading.Lock()
@functools.cached_property
def data(self):
with self._lock:
return expensive_computation()Invalidación de cached_property
Elimine el atributo de la instancia para invalidar la caché y forzar el recálculo en el siguiente acceso.
import functools
class Report:
@functools.cached_property
def summary(self):
return compute_summary()
r = Report()
_ = r.summary # computed
del r.summary # invalidate
_ = r.summary # recomputedUso de lru_cache como caché de API
Almacene en caché las respuestas de la API durante una sesión para evitar llamadas de red redundantes. Borre la caché cuando necesite datos actualizados.
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) # cachedComprobación rápida
¿Qué método borra todos los resultados almacenados en caché de una función decorada con @lru_cache?
Resumen
@lru_cache almacena en caché los resultados de una función identificados por sus argumentos (que deben ser hashables). @cache es un alias sin límite. @cached_property almacena en caché el cálculo de una propiedad por instancia. Consulte la información con cache_info() y restablezca la caché con cache_clear().
Preguntas frecuentes
¿La lección «functools: lru_cache y cached_property» es gratis?
Sí — el texto completo de «functools: lru_cache y cached_property» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Python Academy, actualiza a CoddyKit PRO. El curso de Python Academy incluye 4 lecciones en total.
¿Qué aprenderé en «functools: lru_cache y cached_property»?
Almacene en caché cálculos costosos con lru_cache y cached_property. Practicas Python Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Python Academy?
No se requiere experiencia previa. Python Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «functools: lru_cache y cached_property»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Python Academy?
Sí. Cada lección de Python Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- itertools: iteradores infinitos y finitos
- itertools: combinatoria
- functools: partial y reduce
- functools: lru_cache y cached_property