Loading PyCodeIt workspace...
In technical software engineering interviews, tracing Python decorators reveals how cleanly you track lexical closure lifecycles. Decorators modify call paths by wrapping functions inside wrapper configurations. This process intercepts runtime parameters without permanently restructuring the initial block logic.
Theoretical Blueprint:A decorator operates like a secure security checkpoint wrapped around an inventory warehouse. The warehouse storage remains structurally un-mutated, but the check-point interceptor adds validation steps both before and after trucks enter the facility boundaries.
Common Developer Trap:A common mistake is assuming decorators execute only when the decorated function gets triggered. In reality, the outer decorator block evaluates instantly when the module definition is imported into memory, binding the wrapper references beforehand.
def my_decorator(func):
def wrapper():
print("Before")
func()
print("After")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()Before
Hello!
AfterThe `@my_decorator` syntax overrides `say_hello` to point directly to `wrapper()`. Executing `say_hello()` prints `'Before'`, calls `func() -> 'Hello!'`, and prints `'After'`.
def star(func):
return lambda: '*' + func() + '*'
def dollar(func):
return lambda: '$' + func() + '$'
@star
@dollar
def greet():
return 'Hi'
print(greet())*$Hi$*Inner decorator `@dollar` runs first returning `'$Hi$'`. Outer decorator `@star` runs second wrapping that into `'*$Hi$*'`. Output: `*$Hi$*`.
def make_counter():
count = 0
def inc():
nonlocal count
count += 1
return count
return inc
c = make_counter()
print(c(), c(), c())1 2 3Because `count` is retained in the closure memory, each consecutive invocation `c()` increments the state: `1`, then `2`, then `3`.
from functools import wraps
def my_dec(func):
@wraps(func)
def wrapper(*args):
return func(*args)
return wrapper
@my_dec
def task():
"""Task doc."""
pass
print(task.__name__, task.__doc__)task Task doc.`@functools.wraps` cleanly preserves original function metadata. Output: `task Task doc.`.