Obiective:
- Înțelegerea conceptului de decorator în Python
- Familiarizarea cu sintaxa și utilizarea decoratorilor
- Învățarea unor exemple de aplicare a decoratorilor
Introducere
Decoratorii sunt un concept important și puternic în limbajul de programare Python. Ei permit modificarea sau extinderea comportamentului unei funcții sau metode, fără a modifica codul acesteia. În această lecție, vom învăța cum să scriem și să folosim decoratori în Python.
Funcții ca obiecte
În Python, funcțiile sunt obiecte de primă clasă. Acest lucru înseamnă că ele pot fi atribuite unei variabile, pot fi trimise ca argument unei alte funcții sau pot fi returnate ca o valoare de către o altă funcție. Această caracteristică stă la baza conceptului de decorator.
def salut(nume):
return f"Salut, {nume}!"
mesaj = salut("Andrei")
print(mesaj) # Output: Salut, Andrei!
func = salut
mesaj = func("Ioana")
print(mesaj) # Output: Salut, Ioana!
Funcții de înaltă ordine (Higher-order functions)
Funcțiile de înaltă ordine sunt funcții care pot primi ca argument alte funcții sau pot returna alte funcții. Acestea sunt folosite în mod frecvent în programarea funcțională și permit crearea de soluții elegante și concise pentru probleme complexe.
def aplică(func, valoare):
return func(valoare)
def pătrat(x):
return x ** 2
rezultat = aplică(pătrat, 5)
print(rezultat) # Output: 25
Decoratori simpli
Un decorator este o funcție care primește o funcție ca argument și întoarce o altă funcție care încorporează sau extinde comportamentul funcției inițiale. Decoratorii sunt utilizați pentru a modifica sau extinde comportamentul unei funcții sau metode, fără a modifica codul acesteia.
def decorator(func):
def func_decorată(*args, **kwargs):
print("Înainte de apelul funcției")
rezultat = func(*args, **kwargs)
print("După apelul funcției")
return rezultat
return func_decorată
def salut(nume):
return f"Salut, {nume}!"
salut_decorat = decorator(salut)
mesaj = salut_decorat("Andrei")
print(mesaj)
Sintaxa decoratorilor
Python oferă o sintaxă specială pentru aplicarea decoratorilor, folosind operatorul @. Aceasta permite aplicarea unui decorator unei funcții sau metode într-un mod mai concis și ușor de înțeles.
@decorator
def salut(nume):
return f"Salut, {nume}!"
mesaj = salut("Andrei")
print(mesaj)
Decoratori cu argumente
Decoratorii pot primi argumente, care pot fi folosite pentru a personaliza comportamentul acestora. Pentru a crea un decorator cu argumente, trebuie să înlocuim funcția decorator cu o altă funcție care primește argumentele și returnează funcția decorator.
def decorator_cu_argumente(prefix):
def decorator(func):
def func_decorată(*args, **kwargs):
print(f"{prefix}: Înainte de apelul funcției")
rezultat = func(*args, **kwargs)
print(f"{prefix}: După apelul funcției")
return rezultat
return func_decorată
return decorator
@decorator_cu_argumente("[INFO]")
def salut(nume):
return f"Salut, {nume}!"
mesaj = salut("Andrei")
print(mesaj)
Exemple de aplicare a decoratorilor
1. Decorator pentru măsurarea timpului de execuție
import time
def cronometru(func):
deffunc_decorată(*args, **kwargs):
start = time.time()
rezultat = func(*args, **kwargs)
durata = time.time() - start
print(f"Timpul de execuție al funcției {func.__name__}: {durata:.4f} secunde")
return rezultat
return func_decorată
@cronometru
def funcție_lentă():
time.sleep(2)
funcție_lentă()
2. Decorator pentru memoizare (optimizarea timpului de execuție)
def memoizare(func):
cache = {}
def func_decorată(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return func_decorată
@memoizare
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(30))
3. Decorator pentru verificarea drepturilor de acces
def verifică_drepturi_acces(rol):
def decorator(func):
def func_decorată(*args, **kwargs):
if isinstance(args[0], dict) and args[0].get("rol") == rol:
return func(*args, **kwargs)
raise PermissionError("Acces nepermis!")
return func_decorată
return decorator
@verifică_drepturi_acces("admin")
def modifică_configurație(user, config):
print("Configurația a fost modificată!")
utilizator = {"nume": "Andrei", "rol": "admin"}
configurație = {"opțiune": "valoare"}
modifică_configurație(utilizator, configurație)
Concluzie
În această lecție, am învățat despre decoratori în Python, cum să scriem și să folosim decoratori pentru a modifica sau extinde comportamentul funcțiilor și metodelor. Decoratorii sunt o caracteristică puternică și flexibilă a limbajului Python și pot fi folosiți într-o varietate de situații pentru a îmbunătăți și optimiza codul.