Python « : » Decorators für Zeitmessung », Wiederholung, Caching und Validierung

Python ":" Decorators für Zeitmessung », Wiederholung, Caching und Validierung
3 Minuten Lesezeit

Python-Decorators ermöglichen es, einer Funktion gemeinsame Verhaltensweisen wie Zeitmessung, Wiederholungsversuche, Caching oder Argumentenvalidierung hinzuzufügen, ohne ihren internen Code zu ändern. In einem auf Machine Learning Mastery veröffentlichten Tutorial erläutert der Autor ihre Funktionsweise und zeigt, wie man zuverlässige Decorators erstellt, ohne Ausnahmen zu verschleiern.

  • Decorators ergänzen Funktionen um Zusatzverhalten, ohne deren Code zu ändern.
  • functools.wraps erhält Namen und Dokumentation der ursprünglichen Funktion.
  • Wiederholungsversuche sind nur bei Aufrufen sicher, die zweimal ohne Folgen laufen können.
  • Geschäftslogik gehört in die Funktion, nicht in den Decorator.

Ausgangspunkt ist ein Datenverarbeitungsmodul aus drei Funktionen, die im Laufe der Zeit zusätzliche Aufgaben übernommen haben. Laut Tutorial prüft eine Funktion, ob ihr Pfad existiert, bevor sie Embeddings lädt, eine andere wiederholt ihre Anfragen in einer Schleife mit time.sleep(), und die dritte misst ihre Ausführungszeit und speichert ihre Ergebnisse in einem Wörterbuch. Dieser manuell hinzugefügte Randcode variiert von Funktion zu Funktion, und jede neue Funktion könnte eine weitere Variante einführen.

Ein Decorator, eine einfache Zuweisung

Ein Decorator ist eine Funktion, die eine Funktion als Argument nimmt und einen Wrapper zurückgibt, also eine Hülle, die Code vor und nach dem ursprünglichen Aufruf ausführt. Das Tutorial erinnert daran, dass die Syntax @ einer Neuzuweisung des Funktionsnamens entspricht, was das Python-Glossar als syntaktischen Zucker bezeichnet. Der Decorator wird daher nur einmal ausgeführt, und zwar zum Zeitpunkt der Funktionsdefinition.

Der Wrapper behält die ursprüngliche Funktion dank eines Closures, einem Mechanismus, bei dem eine innere Funktion Zugriff auf die Variablen der sie umschließenden Funktion behält. Die Parameter *args und **kwargs übergeben die Argumente, und das Ergebnis wird unverändert zurückgegeben. Ohne weitere Vorkehrungen ersetzt der Wrapper jedoch den Namen und die Dokumentation der Funktion. Das Tutorial empfiehlt daher die Verwendung von functools.wraps, das diese Metadaten sowie das Attribut __wrapped__ kopiert, das den Zugriff auf die undekorierte Funktion während der Tests ermöglicht.

Vier Randverhaltensweisen

Der Decorator für die Zeitmessung basiert auf time.perf_counter(), einer Uhr zur Berechnung von Zeitdauern, nicht von Datumsangaben. In einem try/finally-Block platziert, zeigt er die Dauer auch dann an, wenn die Funktion fehlschlägt, wobei die Ausnahme weiterhin an den Aufrufer weitergereicht wird.

Der Decorator für Wiederholungsversuche ist eine Fabrik, die Optionen wie max_attempts, delay und die wieder aufzunehmenden Ausnahmen akzeptiert. Er wiederholt nur konfigurierte Ausnahmen, damit ein Programmierfehler nicht als Netzwerkproblem behandelt wird. Beim letzten Versuch löst ein bloßes raise die ursprüngliche Ausnahme erneut aus. Das Tutorial weist jedoch auf eine Einschränkung hin: Dieser Ansatz ist nur sicher für Aufrufe, die zweimal ohne Konsequenzen ausgeführt werden können. Eine Zahlung oder das Senden einer Nachricht erfüllen dieses Kriterium nicht.

Für das Caching empfiehlt das Tutorial functools.lru_cache, das die Ergebnisse der letzten Aufrufe bis zu einem Limit von maxsize (z.B. 256) speichert. Seine Einschränkungen liegen in seiner Implementierung: Die Argumente müssen hashbar sein, und eine Funktion, die ein veränderbares Objekt zurückgibt, kann unerwartete Effekte haben. Die Validierung schließlich verwendet inspect.signature(), um Argumente mit Parameternamen zu verknüpfen, selbst wenn sie über Position oder mit ihrem Standardwert übergeben werden, und wendet dann vor dem Aufruf einfache Regeln an.

Das Tutorial schließt mit einer Vorsichtsregel: Ein Decorator sollte nicht über die Geschäftslogik der Funktion entscheiden. Wenn das Verhalten von den Daten abhängt, ist es besser, es in der Funktion oder in einem Datenmodell für die Validierung unterzubringen. Wenn mehrere Decorators gestapelt werden, ist ihre Anwendungsreihenfolge wichtig, da der oberste der äußerste Wrapper ist.

S’abonner
Notification pour
guest

0 Commentaires
Le plus ancien
Le plus récent Le plus populaire
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x