Els decoradors en Python són una característica poderosa que permet modificar el comportament de funcions o mètodes de manera elegant i reutilitzable. Són una forma de "meta-programació", ja que permeten definir funcions que poden modificar altres funcions.
Continguts
Què és un Decorador?
Un decorador és una funció que pren una altra funció com a argument i retorna una nova funció amb funcionalitat afegida. Els decoradors són molt útils per afegir comportaments comuns a múltiples funcions sense duplicar codi.
Sintaxi dels Decoradors
La sintaxi bàsica d'un decorador és la següent:
Això és equivalent a:
Decoradors Simples
Vegem un exemple senzill d'un decorador que imprimeix un missatge abans i després de l'execució d'una funció.
def simple_decorator(func): def wrapper(): print("Abans de la funció") func() print("Després de la funció") return wrapper @simple_decorator def say_hello(): print("Hola!") say_hello()
Explicació del Codi
simple_decorator
és el decorador que pren una funciófunc
com a argument.wrapper
és la funció interna que afegeix funcionalitat abans i després de cridarfunc
.@simple_decorator
aplica el decorador a la funciósay_hello
.
Decoradors amb Arguments
Els decoradors també poden acceptar arguments. Per fer-ho, cal definir una funció que retorni el decorador.
def decorator_with_args(arg1, arg2): def decorator(func): def wrapper(*args, **kwargs): print(f"Arguments del decorador: {arg1}, {arg2}") return func(*args, **kwargs) return wrapper return decorator @decorator_with_args("Hola", "Món") def greet(name): print(f"Hola, {name}!") greet("Python")
Explicació del Codi
decorator_with_args
és una funció que pren arguments i retorna un decorador.decorator
és el decorador que pren la funciófunc
com a argument.wrapper
és la funció interna que afegeix funcionalitat abans de cridarfunc
.
Decoradors Multiples
És possible aplicar múltiples decoradors a una sola funció. Els decoradors s'apliquen de dalt a baix.
def decorator1(func): def wrapper(): print("Decorador 1") func() return wrapper def decorator2(func): def wrapper(): print("Decorador 2") func() return wrapper @decorator1 @decorator2 def say_hello(): print("Hola!") say_hello()
Explicació del Codi
@decorator2
s'aplica primer asay_hello
.@decorator1
s'aplica després a la funció resultant de@decorator2
.
Decoradors de Classe
Els decoradors també poden ser aplicats a mètodes dins de classes.
def method_decorator(func): def wrapper(self, *args, **kwargs): print("Abans del mètode") result = func(self, *args, **kwargs) print("Després del mètode") return result return wrapper class MyClass: @method_decorator def display(self): print("Mètode de la classe") obj = MyClass() obj.display()
Explicació del Codi
method_decorator
és un decorador que pren un mètode de classefunc
com a argument.wrapper
afegeix funcionalitat abans i després de cridarfunc
.
Exercicis Pràctics
Exercici 1: Decorador de Temps d'Execució
Crea un decorador que mesuri el temps d'execució d'una funció.
import time def time_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"Temps d'execució: {end_time - start_time} segons") return result return wrapper @time_decorator def slow_function(): time.sleep(2) print("Funció lenta") slow_function()
Exercici 2: Decorador de Comptador de Crides
Crea un decorador que compti el nombre de vegades que una funció és cridada.
def call_counter(func): def wrapper(*args, **kwargs): wrapper.calls += 1 print(f"Crides: {wrapper.calls}") return func(*args, **kwargs) wrapper.calls = 0 return wrapper @call_counter def greet(name): print(f"Hola, {name}!") greet("Python") greet("World")
Conclusió
Els decoradors són una eina poderosa en Python que permeten modificar el comportament de funcions i mètodes de manera elegant i reutilitzable. Hem vist com crear decoradors simples, amb arguments, múltiples decoradors i decoradors de classe. També hem practicat amb alguns exercicis per reforçar els conceptes apresos.
En el següent tema, explorarem els generadors, una altra característica avançada de Python que permet treballar amb seqüències de dades de manera eficient.
Curs de Programació en Python
Mòdul 1: Introducció a Python
- Introducció a Python
- Configuració de l'Entorn de Desenvolupament
- Sintaxi de Python i Tipus de Dades Bàsics
- Variables i Constants
- Entrada i Sortida Bàsiques
Mòdul 2: Estructures de Control
Mòdul 3: Funcions i Mòduls
- Definició de Funcions
- Arguments de Funció
- Funcions Lambda
- Mòduls i Paquets
- Visió General de la Biblioteca Estàndard
Mòdul 4: Estructures de Dades
Mòdul 5: Programació Orientada a Objectes
Mòdul 6: Gestió de Fitxers
- Lectura i Escriptura de Fitxers
- Treballant amb Fitxers CSV
- Gestió de Dades JSON
- Operacions amb Fitxers i Directoris
Mòdul 7: Gestió d'Errors i Excepcions
Mòdul 8: Temes Avançats
- Decoradors
- Generadors
- Gestors de Context
- Concurrència: Fils i Processos
- Asyncio per a Programació Asíncrona
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb unittest
- Desenvolupament Guiat per Proves
- Tècniques de Depuració
- Ús de pdb per a la Depuració
Mòdul 10: Desenvolupament Web amb Python
- Introducció al Desenvolupament Web
- Conceptes Bàsics del Framework Flask
- Construcció d'APIs REST amb Flask
- Introducció a Django
- Construcció d'Aplicacions Web amb Django
Mòdul 11: Ciència de Dades amb Python
- Introducció a la Ciència de Dades
- NumPy per al Càlcul Numèric
- Pandas per a la Manipulació de Dades
- Matplotlib per a la Visualització de Dades
- Introducció al Machine Learning amb scikit-learn