Fortgeschrittene Dekorator-Techniken und Anwendungsfälle
Wie Sie gesehen haben, sind Dekorateure (Decorators) ein mächtiges Werkzeug zur Änderung des Funktionsverhaltens in Python. In diesem Abschnitt werden wir einige fortgeschrittenere Dekorator-Techniken und Anwendungsfälle untersuchen.
Dekorieren von Klassen
Dekorateure können auch verwendet werden, um das Verhalten von Klassen zu ändern. Hier ist ein Beispiel für einen Dekorator, der einer Klasse eine Logging-Methode hinzufügt:
def log_class_methods(cls):
class LoggedClass(cls):
def __getattribute__(self, attr):
if callable(super(LoggedClass, self).__getattribute__(attr)):
def logged_method(*args, **kwargs):
print(f"Calling method {attr}")
return super(LoggedClass, self).__getattribute__(attr)(*args, **kwargs)
return logged_method
return super(LoggedClass, self).__getattribute__(attr)
return LoggedClass
@log_class_methods
class MyClass:
def __init__(self, value):
self.value = value
def do_something(self):
print(f"Doing something with value: {self.value}")
obj = MyClass(42)
obj.do_something() ## Output: Calling method do_something
## Doing something with value: 42
In diesem Beispiel nimmt der log_class_methods
-Dekorator eine Klasse als Argument entgegen und gibt eine neue Klasse zurück, die alle Methoden der ursprünglichen Klasse mit einer Logging-Funktion umhüllt.
Dekorateure mit Zustand
Dekorateure können auch Zustände zwischen Funktionsaufrufen aufrechterhalten. Dies kann für Caching, Rate Limiting oder andere zustandsabhängige Operationen nützlich sein. Hier ist ein Beispiel für einen Dekorator, der die Ergebnisse einer Funktion zwischenspeichert:
def cache(func):
cache = {}
def wrapper(*args):
if args in cache:
print("Returning cached result")
return cache[args]
else:
result = func(*args)
cache[args] = result
return result
return wrapper
@cache
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) ## Output: Calculating fibonacci(10)
## 55
print(fibonacci(10)) ## Output: Returning cached result
## 55
In diesem Beispiel verwaltet der cache
-Dekorator ein Wörterbuch von Funktionsaufruf-Argumenten und deren entsprechenden Ergebnissen. Wenn die dekorierte Funktion aufgerufen wird, überprüft der Dekorator zunächst, ob das Ergebnis bereits zwischengespeichert ist, und wenn ja, gibt er das zwischengespeicherte Ergebnis zurück. Andernfalls berechnet er das Ergebnis und speichert es im Cache für die zukünftige Verwendung.
Dekorator-Fabriken
Manchmal möchten Sie möglicherweise Dekorateure erstellen, die mit Argumenten konfiguriert werden können. Dies kann mit einer Dekorator-Fabrik erreicht werden, die eine Funktion ist, die einen Dekorator zurückgibt. Hier ist ein Beispiel:
def repeat(n):
def decorator(func):
def wrapper():
result = ""
for _ in range(n):
result += func()
return result
return wrapper
return decorator
@repeat(3)
def say_hello():
return "hello "
print(say_hello()) ## Output: hello hello hello
In diesem Beispiel ist die repeat
-Funktion eine Dekorator-Fabrik, die ein Argument n
nimmt und einen Dekorator zurückgibt, der die ursprüngliche Funktion umhüllt, sie n
Mal aufruft und die Ergebnisse zusammenfügt.
Diese fortgeschrittenen Dekorator-Techniken zeigen die Flexibilität und Mächtigkeit von Dekoratoren in Python. Durch die Verwendung von Dekoratoren können Sie wiederverwendbaren, modularen und leicht wartbaren Code erstellen, der einfach erweitert und an Ihre Bedürfnisse angepasst werden kann.