Skip to content

Beginning of the lesson

Decorators in Python

Wrap a function in extra behaviour without touching its code

Big Idea: A decorator is a function that takes another function, wraps it in some extra behaviour, and returns the wrapped version. The @decorator line is just a clean shortcut for reassigning a function to its wrapped self. This lets you add logging, timing, caching or access checks to many functions without editing any of them.
By the end you will be able to:
  • explain why functions are first-class objects,
  • write a nested wrapper function that closes over another function,
  • build a decorator and apply it with @,
  • forward any arguments with *args, **kwargs,
  • preserve the original name and docstring with functools.wraps.

1. Functions are first-class objects

Before decorators make sense, remember one fact: in Python a function is an ordinary object, just like an int or a list. You can store it in a variable, put it in a list, pass it into another function as an argument, and even return it from a function.

def shout(text):
    return text.upper()

yell = shout           # store the function object (no parentheses!)
print(yell("hello"))   # HELLO

def run_twice(func, value):
    return func(value) + " " + func(value)

print(run_twice(shout, "hi"))   # HI HI

Notice yell = shout has no parentheses: we copy the function itself, not its result. This ability to pass functions around is exactly what a decorator relies on.

2. Nested functions and closures

You can define a function inside another function. The inner function can read variables from the outer one, and it keeps a reference to them even after the outer function has finished. An inner function that remembers values from its enclosing scope is called a closure.

def make_multiplier(factor):
    def multiply(n):
        return n * factor      # 'factor' comes from the outer scope
    return multiply            # return the inner function object

triple = make_multiplier(3)
print(triple(10))   # 30
print(triple(4))    # 12

make_multiplier returns the inner multiply function, which still remembers factor = 3. A decorator is built exactly this way: an outer function that defines and returns an inner wrapper.

Continue this lesson on YourAIZone

The full lesson has the complete explanation, worked examples, common mistakes, tests with instant checking and an AI tutor. Start right away as a guest, or create an account to keep your progress.

In the full lesson

  • The complete explanation
  • Worked examples
  • Common mistakes and how to avoid them
  • Test questions: 15
  • AI tutor that answers questions about the topic
  • Progress tracking for students, parents and teachers