Stellen Sie sich vor, Sie entwickeln eine Webanwendung und müssen jeden API-Aufruf protokollieren, Benutzerzugriffsrechte überprüfen und die Ausführungszeit von Funktionen messen. Natürlich können Sie denselben Code in jede Funktion kopieren, aber es gibt einen eleganteren Weg — Dekorateure. Dies ist eines der leistungsstärksten Python-Tools, mit dem Sie das Verhalten von Funktionen ändern können, ohne deren Quellcode zu ändern.
Was sind Dekorateure?
Ein Dekorator ist eine Funktion, die eine andere Funktion als Argument annimmt und eine neue Funktion mit erweiterter Funktionalität zurückgibt. Klingt kompliziert? Eigentlich ist alles einfacher als es scheint.
def my_decorator(func):
def wrapper():
print("Something happens before the function is called")
func()
print("Something happens after calling the function")
return wrapper
@my_decorator
def say_hello():
print("Hi!")
say_hello()Ergebnis der Ausführung:
Что-то происходит до вызова функции
Привет!
Что-то происходит после вызова функцииDas Symbol @ ist ein Python-Syntaxzucker. Die Eingabe @my_decorator vor der Funktion entspricht say_hello = my_decorator(say_hello).
Dekorateure mit Argumenten
Aber was ist, wenn unsere Funktion Parameter akzeptiert? Dazu verwenden wir *args und **kwargs:
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(times=3)
def greet(name):
print(f"Hi, {name}!")
greet("Alexey")Fazit:
Привет, Алексей!
Привет, Алексей!
Привет, Алексей!Hier haben wir einen Dekorator mit einem Parameter erstellt, der den Funktionsaufruf eine bestimmte Anzahl von Malen wiederholt.

Praktische Beispiele von Dekorateuren
Messung der Ausführungszeit
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"The {func.__name__} function was executed in {end - start:.4f} seconds")
return result
return wrapper
@timer
def heavy_computation():
time.sleep(2)
return "Done"
heavy_computation()Beachten Sie @wraps(func) — dies ist ein eingebauter Dekorateur aus dem Modul functools, der die Metadaten der Originalfunktion (Name, Dokumentation usw.) speichert.
Zwischenspeichern von Ergebnissen
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(100)) # Sofortige Ausführung dank CachingÜberprüfung der Zugriffsrechte
def require_auth(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
if not user.get('is_authenticated'):
raise PermissionError("Authorization required")
return func(user, *args, **kwargs)
return wrapper
@require_auth
def delete_account(user, account_id):
print(f"Account {account_id} has been deleted")
user = {'is_authenticated': True, 'username': 'admin'}
delete_account(user, 123)Dekorateurketten
Dekorateure können kombiniert werden, indem mehrere auf eine Funktion angewendet werden:
@timer
@memoize
def complex_calculation(x, y):
time.sleep(1)
return x ** y
# Der erste Anruf dauert ~1 Sekunde
complex_calculation(2, 10)
# Der zweite Aufruf erfolgt sofort (das Ergebnis wird zwischengespeichert)
complex_calculation(2, 10)Dekoratoren werden von unten nach oben angewendet, d.h. zuerst memoize, dann timer.
Klassen als Dekorateure
Dekorateure müssen keine Funktionen sein. Sie können Klassen verwenden:
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"Call #{self.count} of the {self.func.__name__} function"__}")
return self.func(*args, **kwargs)
@CountCalls
def process_data():
print("Processing data...")
process_data()
process_data()
process_data()
Eingebaute Python-Dekorateure
Python bietet mehrere nützliche eingebaute Dekorateure:
@property- wandelt die Methode in ein Klassenattribut um@staticmethod— erstellt eine statische Methode@classmethod- erstellt eine Klassenmethode@functools.lru_cache— Zwischenspeicherung mit Größenbeschränkung@dataclass- automatische Erstellung von Klassenmethoden
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_function(param):
# Komplexe Berechnungen
return param * 2Wann man Dekorateure verwendet
Dekoratoren sind ideal für Aufgaben, die auf viele Funktionen angewendet werden müssen: Protokollierung, Validierung von Eingabedaten, Ausnahmebehandlung, Zugriffskontrolle, Caching, Leistungsmessung, Wiederholungslogik bei Netzwerkfehlern. Sie helfen, das DRY-Prinzip (Don't Repeat Yourself) einzuhalten und den Code sauberer und klarer zu machen.
Potenzielle Probleme
Trotz aller Macht der Dekorateure müssen Sie sich an einige Punkte erinnern. Die übermäßige Verwendung von Dekoratoren kann das Debuggen von Code erschweren. Dekorateure verursachen geringe Gemeinkosten für die Leistung. Es ist wichtig, immer @wraps zu verwenden, um Funktionsmetadaten zu speichern. Ketten vieler Dekorateure können die Lesbarkeit des Codes beeinträchtigen.
Zusammenfassung
Dekoratoren sind eine elegante Möglichkeit, die Funktionalität von Code zu modifizieren und zu erweitern, ohne ihn zu ändern. Sie werden häufig in beliebten Frameworks wie Flask und Django verwendet, und wenn Sie verstehen, wie sie funktionieren, wird Ihr Leben als Entwickler viel einfacher. Beginnen Sie mit einfachen Dekorateuren für die Protokollierung oder Zeitmessung, und nach und nach werden Sie immer mehr Situationen finden, in denen sie nützlich sind.
Möchten Sie Dekorateure und andere erweiterte Python-Funktionen in der Praxis beherrschen?
Anlage Kodik wurde speziell entwickelt, damit Sie in einem angenehmen Tempo programmieren lernen können, mit verständlichen Erklärungen auf Deutsch und realen Beispielen aus der Praxis. Wir erklären komplexe Themen in einfacher Sprache – von den Grundlagen bis hin zu professionellen Techniken. Jede Lektion ist so aufgebaut, dass Sie sich nicht nur die Syntax merken, sondern auch verstehen, wie Sie Ihr Wissen in realen Projekten anwenden können.
Und wenn Sie während des Trainings Fragen haben, sind Sie herzlich eingeladen, sich an unser Telegram-Kanal! Dies ist eine lebendige Entwickler-Community, in der Sie jede Frage stellen und eine detaillierte Antwort erhalten können. Unsere Atmosphäre ist freundlich und informativ — jeden Tag analysieren wir Top-Themen in der Entwicklung, teilen unsere Erfahrungen und helfen uns gegenseitig zu wachsen. Werden Sie Teil von Kodik — beginnen Sie Ihre Reise in die Welt der Programmierung mit Menschen, die wirklich verstehen, wie man das Lernen effektiv und interessant gestaltet!
