CodeBlanks Logo Icon CodeBlanks

Function decorator

Learn to write your own function decorator.

Wrapping functions with arguments

A decorator can wrap any function. The wrapper may have zero, one or more parameters. The general solution: use *args, **kwargs to make the wrapper flexible.

Example: def wrapper(*args, **kwargs):\n return fn(*args, **kwargs). The wrapper then forwards whatever parameters arrive to the target. A fixed-parameter wrapper works only with specific signatures; the flexible signature is a common choice.

The two-layer structure

A decorator is a function that takes another function. Inside it a new function (the wrapper) is defined and returned. So a decorator is a higher-order function: it takes a function and returns a function.

Call order: @name is seen → name(target) is called → the wrapper is returned → the user calls the wrapper → the wrapper calls the target. This two-layer design gives decorators flexibility; parameterized decorators can have three layers.

Practice Write a flexible-signature decorator

Define a decorator named double. Start with def double(fn):; inside, define def wrapper(*args, **kwargs):. The wrapper body should have result = fn(*args, **kwargs) and return result * 2. End with return wrapper. Decorate def add(a, b): with @double, body return a + b. Finally call print(add(3, 4)).

Starter code

main.py
# Write the double decorator and the add function

Sample solution

main.py
# Write the double decorator and the add function
def double(fn):
    def wrapper(*args, **kwargs):
        result = fn(*args, **kwargs)
        return result * 2
    return wrapper

@double
def add(a, b):
    return a + b

print(add(3, 4))

Expected output

14

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Complete the wrapper signature

Question
def wrapper(____, **kwargs):
    return fn(*args, **kwargs)
Answer
def wrapper(*args, **kwargs):
    return fn(*args, **kwargs)

Explanation: *args collects positional arguments.

2 What must a decorator return?

  • A list
  • A class instance
  • A number
  • A new function Correct answer

Explanation: A decorator returns a new function that replaces the wrapped one.

3 Match the decorator layers

Term Meaning
def call(fn) Outer layer
def wrapper(*args) Inner layer
return fn(...) Target call
return wrapper Return wrapper

All lessons in Intermediate