Question presented to candidate:
"Writing @timer is easy. Now I want @retry(times=3) or @repeat(3), where the decorator takes its own arguments. How do you write that, and what does Python actually do with the @repeat(3) line?"
What a strong answer should cover:
@repeat(3)first callsrepeat(3), which must return a decorator; that decorator is then applied:f = repeat(3)(f).- Three layers: the factory takes the options, the decorator takes the function, the wrapper takes the call arguments; options live in closure cells.
- Timing: the factory and the decorator both run once at definition time; only the wrapper runs per call.
functools.wraps(func)goes on the innermost wrapper.- The classic bug of using a factory without parentheses (
@repeat), and how to support both@decoand@deco(opt=...)withfunc=Noneplus keyword-only options. - Alternatives: a class whose
__init__takes the options and__call__takes the function; standard-library examples such asfunctools.lru_cache(maxsize=...).
Code / implementation expected: Yes β a parameterised decorator such as repeat(n) or retry(times, exceptions), written live.