Python Academy · Les

Aangepaste decorators schrijven

Maak decorators met wrapperfuncties en functools.wraps.

Les 2 van 414 stappen

Aangepaste decorators schrijven is een gratis Python Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Python Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Python Academy bevat in totaal 4 lessen.

Inleiding

Decorators zijn functies die andere functies omhullen en gedrag toevoegen vóór of na de uitvoering, zonder het origineel te wijzigen.

Wat is een decorator?

@decorator boven een functie is syntactische verkorting voor: func = decorator(func). De decorator ontvangt de functie en retourneert een wrapper.
def shout(func):
    def wrapper(*a, **kw):
        result = func(*a, **kw)
        return str(result).upper()
    return wrapper
@shout
def greet(name): return f'hello {name}'
print(greet('Alice'))

Het wrapperpatroon

De wrapperfunctie heeft dezelfde signatuur als het origineel. De functie roept het origineel binnen zichzelf aan en voegt eromheen gedrag toe.
def timer(func):
    import time
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f'{func.__name__} took {time.time()-start:.4f}s')
        return result
    return wrapper
@timer
def slow(): import time; time.sleep(0.01)
slow()

functools.wraps

@wraps(func) op de wrapper behoudt de __name__, __doc__ en __annotations__ van de oorspronkelijke functie.
from functools import wraps
def log(func):
    @wraps(func)
    def wrapper(*a, **kw):
        print(f'calling {func.__name__}')
        return func(*a, **kw)
    return wrapper
@log
def add(a, b): return a + b
print(add.__name__)
add(1, 2)

Decorator met argumenten

Een decorator met argumenten heeft nog een extra niveau van omhulling nodig: een fabrieksfunctie die de argumenten ontvangt en de decorator retourneert.
def repeat(n):
    def decorator(func):
        from functools import wraps
        @wraps(func)
        def wrapper(*a, **kw):
            for _ in range(n): func(*a, **kw)
        return wrapper
    return decorator
@repeat(3)
def hi(): print('hi')
hi()

Decorators stapelen

Meerdere decorators worden van onder naar boven gestapeld: @d2 @d1 betekent func = d2(d1(func)). De buitenste decorator (bovenste) wordt als laatste uitgevoerd.
def bold(f):
    from functools import wraps
    @wraps(f)
    def w(*a,**k): return '<b>' + f(*a,**k) + '</b>'
    return w
def italic(f):
    from functools import wraps
    @wraps(f)
    def w(*a,**k): return '<i>' + f(*a,**k) + '</i>'
    return w
@bold
@italic
def text(): return 'hello'
print(text())

Decorator op basis van een klasse

Een klasse met __call__ kan een decorator zijn. De klasse bewaart de toestand tussen aanroepen.
class Counter:
    def __init__(self, func): self.func,self.count=func,0
    def __call__(self, *a, **kw):
        self.count+=1
        return self.func(*a, **kw)
@Counter
def greet(name): return f'hi {name}'
greet('Alice'); greet('Bob')
print(greet.count)

Decorator voor memoization

Cache eerdere resultaten om herberekening te voorkomen: if args in cache: return cache[args]. functools.lru_cache doet dit ingebouwd.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
    if n < 2: return n
    return fib(n-1) + fib(n-2)
print(fib(30))

Decorator voor autorisatie

Decorators worden vaak gebruikt voor toegangsbeheer: controleer of de gebruiker is ingelogd voordat je de functie uitvoert.
def requires_auth(func):
    from functools import wraps
    @wraps(func)
    def wrapper(user, *a, **kw):
        if not user.get('authenticated'):
            raise PermissionError('Not authenticated')
        return func(user, *a, **kw)
    return wrapper
@requires_auth
def dashboard(user): return 'Welcome!'
try: dashboard({'authenticated': False})
except PermissionError as e: print(e)

Decorator voor opnieuw proberen

Omhul een functie om deze bij een fout opnieuw te proberen: for _ in range(retries): try: return func() except Exception: pass
import random
from functools import wraps
def retry(times=3):
    def dec(func):
        @wraps(func)
        def wrapper(*a, **kw):
            for i in range(times):
                try: return func(*a, **kw)
                except Exception as e:
                    if i==times-1: raise
        return wrapper
    return dec
@retry(3)
def flaky():
    if random.random()<0.7: raise ValueError
    return 'ok'
try: print(flaky())
except ValueError: print('failed')

Best practices voor decorators

Gebruik altijd @functools.wraps. Houd decorators gericht op één taak. Documenteer wat ze toevoegen. Test de decorator afzonderlijk van de gedecoreerde functie.
from functools import wraps
def validate_positive(func):
    @wraps(func)
    def wrapper(x, *a, **kw):
        if x <= 0: raise ValueError(f'{x} must be positive')
        return func(x, *a, **kw)
    return wrapper
@validate_positive
def sqrt(x): return x**0.5
print(sqrt(9))

Snelle controle

Wat doet @functools.wraps(func) wanneer je het op een wrapper toepast?

Samenvatting

Decorators: func = decorator(func). Gebruik wrapper(*args, **kwargs). @wraps behoudt metagegevens. Geparametriseerde decorators voegen nog een niveau toe. Stapel ze met meerdere @decorators.

Ga door

Uitstekende voortgang! Ga door om het volgende concept onder de knie te krijgen.
Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
76
Lessen
320

Veelgestelde vragen

Is de les “Aangepaste decorators schrijven” gratis?

Ja — de volledige tekst van “Aangepaste decorators schrijven” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Python Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Python Academy bevat in totaal 4 lessen.

Wat leer ik in “Aangepaste decorators schrijven”?

Maak decorators met wrapperfuncties en functools.wraps. Je oefent met Python Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Python Academy te beginnen?

Ervaring vooraf is niet nodig. Python Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “Aangepaste decorators schrijven”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Python Academy?

Ja. Elke les over Python Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Functies als first-classobjecten
  2. Aangepaste decorators schrijven
  3. De decorator @property
  4. @classmethod en @staticmethod
← Terug naar Python Academy