Praktische Beispiele für Dekorateure
Protokollierungs-Dekorator
Ein häufiger Anwendungsfall für Dekorateure ist die Protokollierung von Funktionsaufrufen. Dies kann für das Debugging, die Überwachung oder die Prüfung nützlich sein.
def log_function_call(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args={args} and kwargs={kwargs}")
return func(*args, **kwargs)
return wrapper
@log_function_call
def add_numbers(a, b):
return a + b
result = add_numbers(2, 3)
print(result)
Dies wird folgendes ausgeben:
Calling add_numbers with args=(2, 3) and kwargs={}
5
Caching-Dekorator
Dekorateure können auch verwendet werden, um die Ergebnisse aufwändiger Funktionsaufrufe zu speichern (cachen), was die Leistung verbessert.
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n <= 1:
return n
else:
return (fibonacci(n-1) + fibonacci(n-2))
print(fibonacci(100))
Der lru_cache
-Dekorator aus dem functools
-Modul bietet eine einfache Möglichkeit, einen Least Recently Used (LRU)-Cache für Funktionsergebnisse zu implementieren.
Zugangskontroll-Dekorator
Dekorateure können verwendet werden, um die Zugangskontrolle zu Funktionen oder Methoden durchzusetzen und sicherzustellen, dass nur autorisierte Benutzer bestimmte Funktionen nutzen können.
from functools import wraps
def require_admin(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not is_admin(args[0]):
raise ValueError("Access denied. You must be an admin.")
return func(*args, **kwargs)
return wrapper
class User:
def __init__(self, name, is_admin):
self.name = name
self.is_admin = is_admin
@require_admin
def delete_user(self, user_to_delete):
print(f"Deleting user: {user_to_delete.name}")
admin = User("LabEx", True)
regular_user = User("John", False)
admin.delete_user(regular_user) ## Funktioniert
regular_user.delete_user(admin) ## Wirft ValueError
In diesem Beispiel überprüft der require_admin
-Dekorator, ob der Benutzer, der die delete_user
-Methode aufruft, ein Administrator ist, bevor die Operation fortgesetzt wird.
Wiederholungs-Dekorator
Dekorateure können auch verwendet werden, um einen Wiederholungsmechanismus für Funktionen zu implementieren, die möglicherweise aufgrund vorübergehender Probleme wie Netzwerkfehler oder API-Ratenlimits fehlschlagen.
import time
from functools import wraps
def retry(max_retries=3, delay=1):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
retries = 0
while retries < max_retries:
try:
return func(*args, **kwargs)
except Exception as e:
print(f"Function {func.__name__} failed. Retrying... ({retries+1}/{max_retries})")
retries += 1
time.sleep(delay)
raise Exception(f"Maximum number of retries ({max_retries}) reached for function {func.__name__}")
return wrapper
return decorator
@retry(max_retries=3, delay=2)
def flaky_function():
## Simulate a flaky function that fails 50% of the time
if random.random() < 0.5:
raise Exception("Oops, something went wrong!")
return "Success!"
print(flaky_function())
In diesem Beispiel wird der retry
-Dekorator die flaky_function
automatisch bis zu 3 Mal wiederholen, mit einer Verzögerung von 2 Sekunden zwischen jedem Versuch, bevor eine Ausnahme ausgelöst wird.
Dies sind nur einige Beispiele für die vielen praktischen Anwendungsfälle von Dekorateuren in Python. Dekorateure sind ein mächtiges und flexibles Werkzeug, das Ihnen helfen kann, modulareren, wartbareren und wiederverwendbaren Code zu schreiben.