In Python sind Dekoratoren seit Version 2.4 Teil der Sprache und ermöglichen es, das Verhalten von Funktionen und Klassen zu modifizieren. Dekoratoren für Funktionsparameter sind ein komplexeres Muster, das manuell implementiert wird, da es im Sprachsyntax keine direkte Unterstützung für solche Dekoratoren gibt. Aber durch Annotationen und Metaprogrammierung kann ihre Funktionalität realisiert werden.
Standardmäßige Dekoratoren wirken auf die gesamte Funktion oder Methode. Manchmal ist es erforderlich, nur einzelne Parameter einer Funktion auf einer bestimmten Abstraktionsebene zu validieren, zu protokollieren oder zu ändern. Zum Beispiel, um den Typ des Arguments zu überprüfen, den Wert des Parameters zu konvertieren oder Eingabebeschränkungen anzuwenden.
Funktionsparameter-Dekoratoren werden als Metadaten (z. B. durch Typannotations) erstellt und in einem externen umhüllenden Dekorator verarbeitet. Das Wesentliche des Musters ist, die benötigten Informationen über die Parameter zu speichern, während der "funktionale" Dekorator diese Informationen zur Verarbeitung der Werte beim Aufruf der Funktion verwendet.
Beispielcode:
import inspect from functools import wraps def positive_param(fn): """Annotation zum zwingenden Überprüfen der Positivität des Arguments.""" fn._positive = True return fn # Externer vollständiger Dekorator def validate_decorator(func): spec = inspect.getfullargspec(func) @wraps(func) def wrapper(*args, **kwargs): bound_args = inspect.signature(func).bind(*args, **kwargs) for name, value in bound_args.arguments.items(): param = func.__annotations__.get(name, None) if getattr(param, '_positive', False) and value <= 0: raise ValueError(f"Argument {name} muss positiv sein") return func(*args, **kwargs) return wrapper @validate_decorator def deposit(amount: positive_param): print(f"Eingezahlt {amount}") deposit(10) # OK deposit(-5) # ValueError
Hauptmerkmale:
Wie unterscheiden sich Parameterdekoren von Standardfunktionsdekoren?
Ein Standarddekodierer umschließt die gesamte Funktion unabhängig von den Parametern. Der Parameterdekoder konzentriert sich auf ein bestimmtes Argument und wird nur auf dieses angewendet, was nicht-standardisierte Techniken zur Verarbeitung und Analyse der Signatur erfordert.
Können Parameterdekore in Python wie in TypeScript oder C# mit der @-Syntax realisiert werden?
Nein, in Python wird die @-Syntax für Dekoratoren nur auf Funktionen und Klassen angewendet, jedoch nicht auf einzelne Parameter einer Funktion. Für Parameter werden Annotationen verwendet, gefolgt von der Verarbeitung der Annotationen beim Umhüllen der Funktion.
Kann man Dekoratoren automatisch auf die Parameter von Funktionsargumenten ohne explizite Annotation anwenden?
Nein, Python wendet Dekoratoren nicht automatisch auf Parameter an, aber man kann einen eigenen Mechanismus implementieren, zum Beispiel durch eine benutzerdefinierte Dekoratorfabrik, die die Signatur der Funktion analysiert und die Parameterwerte beim Aufruf ersetzt.
Ein Entwickler ist überzeugt, dass man @ auf den Parameter anwenden kann, wie in anderen Sprachen, und schreibt:
def f(@validate_positive x): ...
Vorteile:
Nachteile:
Der Entwickler verwendet Annotationen und einen externen Dekorator, wie im obigen Beispiel, und verarbeitet die Parameter durch Signatur und Annotationen:
Vorteile:
Nachteile: