functools
functools proporciona funciones de orden superior para caché, aplicación parcial, reducción y genéricos de envío único (single-dispatch), bloques de construcción comunes en decoradores y APIs.
Busca en todas las páginas de la documentación
functools proporciona funciones de orden superior para caché, aplicación parcial, reducción y genéricos de envío único (single-dispatch), bloques de construcción comunes en decoradores y APIs.
from functools import lru_cache, partial
@lru_cache(maxsize=128)
def fib(n: int) -> int:
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
double = partial(pow, 2)Cuándo usar esto:
__name__if isinstancefrom functools import lru_cache, partial, reduce, singledispatch, wraps
def logger(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
print(f"llamada {fn.__name__}")
return fn(*args, **kwargs)
return wrapper
@logger
@lru_cache(maxsize=32)
def tokenize(text: str) -> tuple[str, ...]:
return tuple(text.lower().split())
@singledispatch
def serialize(value) -> str:
return str(value)
@serialize.register(int)
def _(value: int) -> str:
return f"i:{value}"
def product(nums: list[int]) -> int:
return reduce(lambda a, b: a * b, nums, 1)
if __name__ == "__main__":
print(tokenize("Hello World"))
print(serialize(42))
print(product([2, 3, 4]))
add5 = partial(lambda a, b: a + b, 5)
print(add5(10))Lo que esto demuestra:
@wraps copia metadatos al wrapper para introspección/depuraciónlru_cache requiere argumentos hasheablessingledispatch registra manejadores por tiporeduce pliega un iterable con una función binariamaxsize.partial(func, *args, **kwargs) fija los argumentos iniciales.__eq__ y un método de ordenamiento.@outer
@inner
def f(): ...
# equivale a f = outer(inner(f)) - inner se aplica primerofrom functools import cached_property # 3.8+
class Config:
@cached_property
def heavy(self) -> dict:
return load()cache_clear o no usar caché.maxsize=None sin límites en la caché - Crecimiento de memoria en un espacio de claves infinito. Solución: Establecer un maxsize.partial oscurece la firma - La inspección es menos clara. Solución: Usar un wrapper con parámetros explícitos para APIs públicas.singledispatch no es para múltiples argumentos - Solo considera el tipo del primer argumento. Solución: Usar bibliotecas de multimétodos o lógica manual.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| caché manual con diccionario | Evicción personalizada | Cuando lru_cache es suficiente |
@cache (3.9+) | Espacio de claves pequeño sin límites | Se necesita evicción LRU |
match/case para despachar | Pocos tipos en línea | Extensión abierta a través de módulos |
itertools.accumulate | Fold (plegado) en ejecución sin importar reduce | Solo se necesita un valor final único |
functools.cache es una caché simple sin límites, similar a LRU (3.9+). lru_cache controla el tamaño y las estadísticas.
CPython protege el diccionario de caché para operaciones individuales; aún así, coordina si la función subyacente no es segura para hilos.
Para unir configuraciones en callbacks - partial(send_email, smtp=cfg) en bucles.
Sí, para decoradores públicos - preserva __name__, __doc__, anotaciones para herramientas.
Aceptable para folds funcionales; a menudo es más claro total = 1; for x in nums: total *= x para principiantes.
Registrar en otros módulos con el mismo nombre de función importado - el orden importa.
cached_property almacena en la instancia una vez; lru_cache en los argumentos de la función globalmente.
Se debe definir __eq__ y un método de comparación; los demás se derivan - puede ser más lento que hacerlo manualmente.
fib.cache_info() muestra aciertos/fallos/tamaño máximo/tamaño actual para ajustar.
lru_cache ayuda con llamadas puras costosas; partial tiene un costo insignificante.
wrapsaccumulate vs reduceVersiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.
Revisado por Chris St. John·Última actualización: 19 jul 2026