Skip to content
Forge Learn/Functional Python & Iterators
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Decorators

7 min read

You'll learn to

  • -Explain what a decorator is: a function that wraps another function
  • -Apply a decorator with `@decorator_name` syntax
  • -Build a simple timing or logging decorator from scratch

A decorator is a function that takes another function as input and returns a new function that wraps it, typically adding behavior before and/or after the original runs, without modifying the original function's own code. This directly builds on the closures chapter from the Functions module: a decorator is a closure whose remembered enclosing variable happens to be the function it is wrapping.

Building a Decorator by Hand

Before the @ syntax, look at what a decorator actually is: a function that accepts a function and returns a new function.

A logging "decorator", manually applied first

Notice wrapper takes *args, **kwargs, exactly the accept-anything tool from the earlier functions module, so log_calls can wrap a function with any signature at all, not just ones that take two arguments.

The @decorator Syntax

@decorator_name placed directly above a function definition is exactly equivalent to the manual reassignment above: def add(...): ... followed by add = log_calls(add), just cleaner to read.

The same decorator, applied with @ syntax

A Timing Decorator

Another classic, genuinely useful decorator measures how long a function takes to run, using the time module.

A reusable timing decorator

Foreshadowing: Caching Is Just a Decorator

Here is the payoff for everything in this chapter and the closures chapter before it. What if, instead of timing a function, a wrapper checked whether it had already computed the result for these exact arguments, and returned the cached answer instead of recomputing it?

A tiny cache decorator: this is memoization

This is exactly what memoization is: a cache, keyed by arguments, wrapped around a function that would otherwise repeat expensive work. The Algorithms phase of this course covers memoization for recursive algorithms in depth, and Python's own functools.lru_cache gives you this decorator for free, but the underlying mechanism is precisely the closure-plus-wrapper pattern you just built by hand.

  • -A decorator is a function that takes a function and returns a new (usually wrapping) function.
  • -@decorator_name above a def is sugar for func = decorator_name(func).
  • -A wrapper almost always accepts *args, **kwargs so it can wrap functions of any signature.
  • -A caching decorator is a closure holding a dict, checked and updated on every call. This is memoization, which the next phase of this course (Algorithms) builds on directly.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

Module Assignment is part of Pro

Write real, graded Python for this module - right here in the course.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!