Conținut curs
Gestionarea erorilor și excepțiilor
0/1
Python Intermediar
Despre lecție

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.

python
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.

python
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.

python
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.

python
@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.

python
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

python
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)

python
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

python
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.