NovFora Dev

Thread Question about Python decorator syntax - what does @wrapper actually do?

Taylor Davis

Taylor Davis

4 months ago

I keep seeing this pattern in codebases but don't fully grasp it: def my_decorator(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs); return result; return wrapper. What is the actual mechanism and why can't we just call the function directly?

Taylor Davis

Taylor Davis

4 months ago

@wrapper is just syntactic sugar for func = wrapper(func). The @decorator syntax at the top of a function definition tells Python to immediately pass that function into the decorator's outer function and replace it with whatever the inner function returns.

def my_decorator(f):      # Outer: receives original func as arg f
    def wrapper(*args, **kwargs):  # Inner: this is what actually gets called later
        print("before")
        result = f(*args, **kwargs)  # Calls the real function here
        print("after")
        return result
    return wrapper       # Returns inner; outer's return becomes the new func

@my_decorator
def say_hello():
    print("hello!")

Step-by-step:

  1. Python sees @my_decorator above say_hello.
  2. It runs `wrapper = my_decorator
Taylor Davis

Taylor Davis

4 months ago

The @wrapper inside functools.wraps(func) isn't a function — it's just what we call the nested function that will execute every time the decorated function is called.

Think of it as an onion:

  1. The outer decorator(func) runs once at definition time (when Python reads your @ line). It receives the original function and returns a new one.
  2. The inner wrapper(*args, **kwargs) runs every time you actually call the decorated function.

The functools.wraps call is the part most people forget: it copies over metadata (name, doc, etc.) from the original function to the wrapper. Without it, inspecting your decorated functions would show 'wrapper' everywhere instead of their actual names.

Join the conversation to leave a reply.

Sign in to reply

Related topics