ProgrammatieBackend ontwikkelaar

Wat zijn hoge orde functie decorators in Python, hoe stellen ze je in staat om het 'wrapping' patroon te implementeren, en wat moet je in overweging nemen bij het werken met metadata/documentatie van functies?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

In Python is een hoge orde functie decorator een functie die een andere functie (of klasse) accepteert en een nieuwe functie (of een nieuw gemodificeerde klasse) retourneert. Decorators worden vaak gebruikt om het 'wrapping' patroon te implementeren, waarmee je extra logica (bijvoorbeeld logging, caching, rechtencontrole, enz.) aan bestaande functies kunt toevoegen zonder de oorspronkelijke code te wijzigen.

Om de naam, documentatie en andere metadata van de originele functie te behouden, is het aan te raden om de functie functools.wraps te gebruiken:

import functools def log_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print(f'Calling {func.__name__}') return func(*args, **kwargs) return wrapper @log_decorator def add(a, b): """Voeg twee getallen toe""" return a + b print(add(2, 3)) # Output: Calling add 5 print(add.__name__) # Output: add print(add.__doc__) # Output: Voeg twee getallen toe

Belangrijk punt: zonder functools.wraps verliest de gewrapte functie haar naam, documentatie en andere metadata van de originele functie, wat de debugging en autodocumentatie negatief beïnvloedt.

Misleidende vraag.

Als je een functie decoreert zonder functools.wraps, wat gebeurt er dan met de attributen name en doc van de functie?

Antwoord: Ze worden geërfd van de interne wrapperfunctie (meestal 'wrapper'), en je verliest de originele metadata.

def simple_decorator(func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper @simple_decorator def f(): """Dit is een docstring""" pass print(f.__name__) # Output: 'wrapper' (NIET 'f') print(f.__doc__) # Output: None (en niet 'Dit is een docstring')

Voorbeelden van daadwerkelijke fouten door gebrek aan kennis over de nuances van het onderwerp.


Verhaal

In een project implementeerden ze een geavanceerd systeem van decorators voor logging van API-endpoints, maar gebruikten ze geen functools.wraps. Als gevolg hiervan toonden de autodocumentatie-engine (Swagger/OpenAPI) en introspectiehulpmiddelen de namen van alle endpoints als 'wrapper', en verdween de documentatie. Dit bemoeilijkte ondersteuning, testen en onderhoud aanzienlijk.


Verhaal

Bij het schrijven van unittests met pytest trad er een fout op bij de auto-discovery van tests: testfuncties, gedecoreerd met hun decorators zonder wraps, werden niet gevonden, omdat hun name onjuist was. De reden — pytest zoekt functies op naam.


Verhaal

Bij het traceren van de stack van uitzonderingen wees de stack-trace altijd naar "wrapper", en het was onmogelijk om te begrijpen welke specifieke functie de fout veroorzaakte, aangezien de rootmetadata verloren gingen door het ontbreken van functools.wraps in de gebruikersdecorators.