Modulul standard functools furnizează funcții de ordin superior care acționează asupra altor funcții. Două dintre cele mai utile instrumente pentru cod robust și rapid sunt @cache (pentru memoizarea automată a rezultatelor costisitoare) și @singledispatch (pentru implementarea polimorfismului funcțional elegant, fără lanțuri repetitive de if isinstance(...)).
from functools import cache, lru_cache
# @cache creează un cache infinit în memorie bazat pe argumentele funcției:
@cache
def calculeaza_factori_primi(numar: int) -> list[int]:
print(f"Calcul costisitor pentru {numar}...")
factori = []
d = 2
temp = numar
while d * d <= temp:
if temp % d == 0:
factori.append(d)
temp //= d
else:
d += 1
if temp > 1:
factori.append(temp)
return factori
# Primul apel: execută calculul
print(calculeaza_factori_primi(840)) # Rulează algoritmul
# Al doilea apel cu aceleași argumente: returnează INSTANTANEU din cache-ul RAM!
print(calculeaza_factori_primi(840))
# Verificarea statisticilor de cache:
print(calculeaza_factori_primi.cache_info())
# CacheInfo(hits=1, misses=1, maxsize=None, currsize=1)
@cache vs. @lru_cache: Când folosim fiecare?
@cache: Stochează nelimitat toate rezultatele. Folosiți-l doar dacă spațiul de intrare este mic sau finit (de exemplu, funcții matematice discrete sau citirea unor configurații statice).@lru_cache(maxsize=128): Folosește politica Least Recently Used. Când cache-ul atinge dimensiunea maximă (de exemplu 128 sau 1024 de intrări), cele mai vechi elemente neutilizate sunt eliminate automat pentru a proteja memoria RAM a serverului.
2. Polimorfism Elegant cu @singledispatch
Deseori trebuie să scriem funcții care procesează datele diferit în funcție de tipul primit (de exemplu, o funcție de formatare sau de serializare). Un lanț clasic de if isinstance(x, int): ... elif isinstance(x, list): ... este greu de extins și încalcă principiul Open-Closed din SOLID.
from functools import singledispatch
from datetime import datetime, date
# 1. Definim funcția de bază pentru cazul generic (fallback):
@singledispatch
def formateaza(valoare) -> str:
return str(valoare)
# 2. Înregistrăm implementări specializate pentru fiecare tip:
@formateaza.register
def _(valoare: int) -> str:
return f"{valoare:,} RON".replace(",", ".")
@formateaza.register
def _(valoare: date) -> str:
return valoare.strftime("%d/%m/%Y")
@formateaza.register
def _(valoare: list) -> str:
return "[" + ", ".join(formateaza(x) for x in valoare) + "]"
# Testare:
print(formateaza(1500000)) # "1.500.000 RON"
print(formateaza(date(2026, 10, 24))) # "24/10/2026"
print(formateaza([100, 200])) # "[100 RON, 200 RON]"