{}const=>[]async()letfn</>var
EntwicklungPython

Dekoratoren in Python: Funktionalität erweitern, ohne den Code zu ändern

Erfahren Sie, wie Sie Dekoratoren in Python verwenden, um die Funktionalität elegant zu erweitern. Wir analysieren praktische Beispiele: Protokollierung, Caching, Messung der Ausführungszeit und Überprüfung der Zugriffsrechte. Klare Erklärungen mit Codebeispielen für Anfänger und erfahrene Entwickler.

К

Kodik

Autor

5 Min. Lesezeit

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

🔥 100.000+ Schüler sind bereits bei uns

Genug Theorie gelesen?
Zeit zu coden!

Kodik — eine App, in der du durch Praxis programmieren lernst. KI-Mentor, interaktive Lektionen, echte Projekte.

🤖 KI 24/7
🎓 Zertifikate
💰 Kostenlos
🚀 Jetzt starten
Heute beigetreten

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 * 2

Wann 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!

🎯Hör auf zu zögern

Artikel gefallen?
Zeit zum Üben!

Bei Kodik liest du nicht nur — du schreibst sofort Code. Theorie + Praxis = echte Skills.

Sofortige Praxis
🧠KI erklärt Code
🏆Zertifikat

Keine Registrierung • Keine Karte