ProgrammatieBackend ontwikkelaar

Leg uit hoe decorateurs werken in Python. Wat zijn hun belangrijkste voordelen, hoe worden ze geïmplementeerd en welke nuances kunnen zich voordoen bij hun toepassing?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Decorateurs zijn functies die een andere functie accepteren en een nieuwe functie met uitgebreid of gewijzigd gedrag retourneren. Ze worden vaak gebruikt voor logging, autorisatie, caching, uitvoeringstijd en meer.

Decorateurs worden geïmplementeerd met behulp van closures of klassen die de __call__-methode implementeren. De klassieke syntaxis:

# Eenvoudige decorateur def simple_decorator(func): def wrapper(*args, **kwargs): print("Voor het aanroepen van de functie") result = func(*args, **kwargs) print("Na het aanroepen van de functie") return result return wrapper @simple_decorator def my_func(): print("Hoofdfunctie") my_func()

Dit zal als volgt worden uitgevoerd:

Voor het aanroepen van de functie
Hoofdfunctie
Na het aanroepen van de functie

Het belangrijkste voordeel is de encapsulatie van herhalende logica buiten de hoofd business-logica.

Nuances:

  • Zonder het gebruik van functools.wraps gaat de naam van de oorspronkelijke functie en haar docstring verloren.
  • Als de decorateur argumenten accepteert, moet er een driedubbele geneste functie worden geschreven.

Vraag met een addertje onder het gras

Vraag: "Als ik een functie decoreer met een decorateur en vervolgens probeer de naam van de functie op te vragen via __name__, wat zal ik zien en hoe kan ik de originele naam behouden?"

Antwoord:

Standaard verandert de naam in de naam van de wrapper (meestal wrapper). Om de originele metadata te behouden, gebruik functools.wraps:

import functools def dec(f): @functools.wraps(f) def wrapper(*args): return f(*args) return wrapper @dec def foo(): pass print(foo.__name__) # zal 'foo' afdrukken, en niet 'wrapper'

Voorbeelden van echte fouten door gebrek aan kennis van de nuances van het onderwerp


Verhaal

Bij een grote resource-automatisering was het testsysteem dat gebruik maakte van reflectie op de namen van testfuncties, gebroken na het omhullen van functies met decorateurs. Het probleem was de afwezigheid van functools.wraps.


Verhaal

Een decorateur die logging toevoegde, ondersteunde geen functies met verschillende handtekeningen, omdat *args, **kwargs niet werden gebruikt. Sommige functies faalden stilletjes.


Verhaal

In een project met autorisatie in de REST API implementeerde een ontwikkelaar een decorateur met parameters, maar vergat de functies correct te nesten (er was een tweelaagse nesting in plaats van drie). Hierdoor kon de decorateur geen parameters accepteren.