Entfesselung der Python Decorator Magie!
Lukas Schneider
DevOps Engineer · Leapcell

Python Decorators: Ein mächtiges Programmierwerkzeug
Python Decorators sind ein äußerst mächtiges Werkzeug, das es Programmierern ermöglicht, Funktionen zusätzliche Funktionalität hinzuzufügen, ohne die ursprünglichen Funktionsdefinitionen zu ändern. Diese Funktion erleichtert die Wartung und Erweiterung des Codes und verbessert gleichzeitig die Lesbarkeit und Wiederverwendbarkeit des Codes. Decorators haben eine breite Palette von Anwendungsszenarien, die Bereiche wie Logging, Performance-Tests, Transaktionsverarbeitung, Caching und Berechtigungsüberprüfung abdecken. Dieser Artikel wird im Detail vorstellen, wie man Decorators in Python geschickt einsetzt, um praktische Probleme anhand einiger spezifischer Beispiele zu lösen.
Logging
Im Softwareentwicklungsprozess ist das Logging eine sehr wichtige Aufgabe. Es kann Entwicklern helfen, den Ausführungsablauf des Codes zu verfolgen, Fehler zu beheben und den laufenden Status des Systems zu überwachen. Durch die Verwendung von Decorators können wir Funktionen auf einfache Weise Logging-Funktionalität hinzufügen, ohne manuell Logging-Code in jeder Funktion hinzufügen zu müssen. Dies reduziert nicht nur die Codedopplung, sondern macht auch die Codestruktur übersichtlicher.
import logging def log_decorator(func): def wrapper(*args, **kwargs): logging.info(f"Running '{func.__name__}' with arguments {args} and {kwargs}") return func(*args, **kwargs) return wrapper @log_decorator def say_hello(name): print(f"Hello, {name}!") say_hello("Alice")
Code Erklärung
Der obige Code definiert eine Decorator-Funktion namens log_decorator
. Diese Funktion nimmt eine Funktion func
als Parameter und gibt eine neue Funktion wrapper
zurück. In der Funktion wrapper
wird zuerst logging.info
verwendet, um den Namen der aufgerufenen Funktion und die übergebenen Parameter aufzuzeichnen, dann wird die ursprüngliche Funktion func
aufgerufen und deren Ausführungsergebnis zurückgegeben. Indem man @log_decorator
über die Definition der Funktion say_hello
platziert, wird die Funktion say_hello
durch diesen Decorator dekoriert. Jedes Mal, wenn die Funktion say_hello
aufgerufen wird, wird automatisch Logging aufgezeichnet.
Performance Testing
Bei der Optimierung der Performance müssen wir oft die Ausführungszeit von Code messen, um Performance-Engpässe zu identifizieren und zu optimieren. Decorators können diesen Prozess automatisieren und standardisieren, was es uns erleichtert, die Performance verschiedener Funktionen zu vergleichen und zu analysieren.
import time def timing_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"{func.__name__} took {end_time - start_time:.4f} seconds to run.") return result return wrapper @timing_decorator def slow_function(delay_time): time.sleep(delay_time) slow_function(2)
Code Erklärung
Dieser Code definiert einen timing_decorator
Decorator. Innerhalb der wrapper
-Funktion wird time.time()
verwendet, um die Zeit vor und nach der Funktionsausführung aufzuzeichnen. Durch die Berechnung der Differenz zwischen den beiden wird die Ausführungszeit der Funktion erhalten und ausgegeben. Auf diese Weise wird jedes Mal, wenn eine Funktion, die durch timing_decorator
dekoriert ist, aufgerufen wird, die Ausführungszeit der Funktion automatisch ausgegeben.
Caching Results
Für einige zeitaufwändige Berechnungen, insbesondere für Funktionen mit festen Ein- und Ausgaben, verschwendet die Neuberechnung derselben Ergebnisse viel Zeit und Ressourcen. Die Verwendung von Decorators zum Zwischenspeichern von Ergebnissen kann die Performance erheblich verbessern und unnötige wiederholte Berechnungen vermeiden.
from functools import lru_cache @lru_cache(maxsize=32) def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2) print(fib(10))
Code Erklärung
Hier wird der lru_cache
-Decorator aus dem Modul functools
verwendet. lru_cache
steht für Least Recently Used Cache, und er speichert automatisch die Aufrufergebnisse der Funktion zwischen. Wenn dieselben Parameter erneut aufgerufen werden, wird das zwischengespeicherte Ergebnis direkt zurückgegeben, anstatt die Funktion erneut auszuführen. Der Parameter maxsize
gibt die maximale Kapazität des Cache an. Wenn der Cache diese Kapazität erreicht, wird das am wenigsten kürzlich verwendete Cache-Element entfernt.
Permission Verification
In der Webentwicklung ist es oft notwendig, die Berechtigungen von Benutzern zu überprüfen, um sicherzustellen, dass nur Benutzer mit den entsprechenden Berechtigungen bestimmte Operationen ausführen können. Decorators können uns helfen, diese Funktion elegant zu implementieren, indem sie die Berechtigungsüberprüfungslogik von der Geschäftslogik trennen und die Wartbarkeit des Codes verbessern.
from functools import wraps def permission_required(permission): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): user_permission = kwargs.get('user_permission') if user_permission!= permission: raise Exception("Permission denied") return func(*args, **kwargs) return wrapper return decorator @permission_required('admin') def delete_user(user_id, user_permission): print(f"User {user_id} has been deleted.") delete_user(1, user_permission='admin') # Success delete_user(1, user_permission='guest') # Exception: Permission denied
Code Erklärung
permission_required
ist eine Decorator-Factory-Funktion, die einen permission
-Parameter entgegennimmt, der die erforderliche Berechtigung darstellt. Die innere decorator
-Funktion nimmt eine Funktion func
als Parameter und gibt eine neue wrapper
-Funktion zurück. In der wrapper
-Funktion wird geprüft, ob user_permission
in kwargs
enthalten ist und ob diese Berechtigung mit der erforderlichen permission
übereinstimmt. Wenn nicht, wird eine Ausnahme Permission denied
ausgelöst; andernfalls wird die ursprüngliche Funktion func
ausgeführt.
Parameter Verification
Decorators können auch verwendet werden, um Funktionsparameter zu überprüfen, um sicherzustellen, dass sie bestimmte Bedingungen erfüllen. Dies kann Parameterfehler vor der Ausführung der Funktion erkennen, unnötige Operationen innerhalb der Funktion vermeiden und die Robustheit des Codes verbessern.
from functools import wraps def type_check(correct_type): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): if not all([isinstance(arg, correct_type) for arg in args])): raise ValueError("Incorrect argument type") return func(*args, **kwargs) return wrapper return decorator @type_check(str) def string_repeat(string, times): return string * times print(string_repeat("hello", 3)) # Works string_repeat("hello", "3") # Raises ValueError
Code Erklärung
Die type_check
-Decorator-Factory-Funktion nimmt einen correct_type
-Parameter entgegen, der den erwarteten Parametertyp darstellt. In der wrapper
-Funktion wird die isinstance
-Funktion verwendet, um zu überprüfen, ob alle Positionsargumente vom angegebenen Typ sind. Wenn ein Argumenttyp nicht übereinstimmt, wird eine ValueError
-Ausnahme ausgelöst; andernfalls wird die ursprüngliche Funktion func
ausgeführt.
Conclusion
Decorators bieten eine effiziente und elegante Möglichkeit, die Funktionalität von Funktionen zu erweitern. Sie können uns helfen, funktionale Erweiterungen mit minimalen Codeänderungen zu erreichen. Durch die Beispiele in diesem Artikel können wir die mächtigen Fähigkeiten und flexiblen Anwendungen von Decorators in der tatsächlichen Entwicklung sehen. Die korrekte Verwendung von Decorators kann den Code prägnanter, einfacher zu warten, und die Lesbarkeit und Benutzerfreundlichkeit des Codes verbessern. In der täglichen Programmierung können wir Decorators flexibel einsetzen, um die Codestruktur zu optimieren und die Entwicklungseffizienz gemäß den spezifischen Anforderungen zu verbessern.
Leapcell: Die beste Serverless-Plattform für das Hosten von Python-Apps
Schließlich empfehlen wir die beste Plattform für die Bereitstellung von Python-Diensten: Leapcell
1. Multi - Language Support
- Entwickeln Sie mit JavaScript, Python, Go oder Rust.
2. Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung - keine Anfragen, keine Gebühren.
3. Unschlagbare Kosteneffizienz
- Pay - as - you - go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Millionen Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
4. Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeit-Metriken und Protokollierung für umsetzbare Erkenntnisse.
5. Mühelose Skalierbarkeit und hohe Performance
- Auto - Scaling zur einfachen Handhabung hoher Parallelität.
- Null operativer Aufwand - konzentrieren Sie sich einfach auf das Bauen.
Erfahren Sie mehr in der Dokumentation!
Leapcell Twitter: https://x.com/LeapcellHQ