Python « : » decorators om tijd te meten », opnieuw te proberen, te cachen en te valideren

Python ":" decorators om tijd te meten », opnieuw te proberen, te cachen en te valideren
3 min lezen

Python-decorators maken het mogelijk om aan een functie gemeenschappelijke gedragingen toe te voegen, zoals het meten van de duur, nieuwe pogingen, caching of het valideren van argumenten, zonder de interne code aan te passen. In een tutorial gepubliceerd op Machine Learning Mastery legt de auteur hun werking uit en laat zien hoe je betrouwbare decorators kunt bouwen, zonder uitzonderingen te verbergen.

  • Decorators voegen gedrag toe aan functies zonder hun interne code aan te passen.
  • Een decorator wordt slechts één keer uitgevoerd, op het moment van de definitie van de functie.
  • functools.wraps behoudt de naam, documentatie en toegang tot de oorspronkelijke functie.
  • Een decorator mag de bedrijfslogica niet bepalen, en de volgorde van stapelen telt.

Het uitgangspunt is een gegevensverwerkingsmodule bestaande uit drie functies die in de loop van de weken extra taken zijn gaan uitvoeren. Volgens de tutorial controleert een functie of het pad bestaat voordat het embeddings laadt, een andere herhaalt zijn verzoeken in een lus met time.sleep(), en de derde meet zijn uitvoeringstijd en bewaart de resultaten in een woordenboek. Deze randcode, handmatig toegevoegd, verschilt per functie, en elke nieuwe functie kan een variant introduceren.

Een decorator, een eenvoudige toewijzing

Een decorator is een functie die een functie als argument neemt en een wrapper retourneert, dat wil zeggen een omhulsel dat code uitvoert voor en na de oorspronkelijke aanroep. De tutorial herinnert eraan dat de syntaxis @ gelijk staat aan een hertoewijzing van de functienaam, wat de Python-glossary syntactische suiker noemt. De decorator wordt dus slechts één keer uitgevoerd, op het moment van de definitie van de functie.

De wrapper behoudt de oorspronkelijke functie dankzij een closure, een mechanisme waarbij een interne functie toegang houdt tot de variabelen van de functie die hem omvat. De parameters *args en **kwargs geven de argumenten door, en het resultaat wordt ongewijzigd geretourneerd. Zonder aanvullende voorzorg vervangt de wrapper echter de naam en documentatie van de functie. De tutorial raadt daarom aan om functools.wraps te gebruiken, die deze metadata kopieert, evenals het attribuut __wrapped__, dat toegang geeft tot de niet-gedecoreerde functie tijdens tests.

Vier randgedragingen

De decorator voor het meten van tijd is gebaseerd op time.perf_counter(), een klok die wordt gebruikt om tijdsduur te berekenen en niet voor datums. Geplaatst in een try/finally-blok, geeft het de duur weer zelfs wanneer de functie faalt, waarbij de uitzondering wordt doorgegeven aan de aanroeper.

De decorator voor nieuwe pogingen is een fabriek, die opties accepteert zoals max_attempts, delay en de uitzonderingen die opnieuw moeten worden geprobeerd. Het probeert alleen geconfigureerde uitzonderingen opnieuw, zodat een programmeerfout niet wordt behandeld als een netwerkprobleem. Bij de laatste poging wordt een ‘raise’ zonder argument gebruikt om de oorspronkelijke uitzondering opnieuw te genereren. De tutorial benadrukt echter een beperking: deze aanpak is alleen veilig voor aanroepen die twee keer kunnen worden uitgevoerd zonder gevolgen. Een betaling of het verzenden van een bericht voldoet niet aan dit criterium.

Voor caching raadt de tutorial functools.lru_cache aan, dat de resultaten van de meest recente aanroepen bewaart, tot een maximum van maxsize (bijvoorbeeld 256). De beperkingen houden verband met de implementatie: argumenten moeten hashbaar zijn, en een functie die een wijzigbaar object retourneert kan onverwachte effecten veroorzaken. Voor validatie wordt ten slotte inspect.signature() gebruikt om argumenten te koppelen aan parameternamen, zelfs wanneer ze op positie of met hun standaardwaarde worden doorgegeven, waarna eenvoudige regels worden toegepast vóór de aanroep.

De tutorial eindigt met een voorzichtigheidsregel: een decorator mag niet beslissen over de bedrijfslogica van de functie. Wanneer het gedrag afhangt van de gegevens, is het beter om het in de functie zelf te plaatsen, of in een gegevensmodel voor validatie. Wanneer meerdere decorators worden gestapeld, is de volgorde van toepassing belangrijk, omdat de hoogste de buitenste wrapper is.

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