datarekha
Python Hard Asked at GoogleAsked at StripeAsked at AirbnbAsked at Netflix

How do you write a decorator that accepts its own arguments?

The short answer

You add one more layer of nesting: a factory function that accepts the decorator's arguments and returns the actual decorator. The @syntax then calls the factory first, and the result decorates the function.

How to think about it

A plain decorator has signature decorator(func) -> func. To give it its own arguments you need one more layer of nesting — a factory that accepts the arguments and returns the decorator. The @ syntax then calls the factory first, and the result is the actual decorator.

What’s really being tested

This is really a closures question in disguise. Interviewers want to see you understand that @retry(max_attempts=3) is just call_api = retry(max_attempts=3)(call_api) — two separate calls. Getting the three levels of nesting right, and using functools.wraps to preserve the original function’s metadata, are the things they’re grading you on.

Step 1 — Understand the three levels

retry(max_attempts, delay)        ← factory (level 1)
  └── decorator(func)             ← actual decorator (level 2)
        └── wrapper(*args, **kwargs)  ← replacement function (level 3)

The factory is called at decoration time (before the function ever runs). The wrapper is called every time the decorated function is invoked.

Step 2 — Build it up piece by piece

Start with a plain decorator, then wrap it in the factory. The arguments become closed-over variables inside the decorator and wrapper.

Step 3 — Always use functools.wraps

Without @functools.wraps(func), the wrapper will have the wrong __name__, __doc__, and __module__. This breaks help(), logging, and any introspection tool.

The key insight — it’s just closures

The factory call returns the decorator, which closes over max_attempts and delay. The decorator returns the wrapper, which closes over func. Three nested closures, each capturing the scope above it. Once you see it that way, the pattern becomes mechanical.

Learn it properly Decorators

Keep practising

All Python questions

Explore further

Skip to content