Python Decorators in 5 Easy Steps (With Simple Code Examples)

June 18, 2025
7 min read
Python, Decorators, Beginners

In Python, a decorator is like a wrapper around a function. You add it on top of a function using @ syntax, and it lets you do something extra every time that function runs—without changing the original code. Sounds confusing? Let’s break it down in 5 simple steps so it clicks.

🧠 Step 1: Functions Are Objects

Functions in Python can be treated like variables. You can assign a function to another variable and call it from there.

def recipe():
    print("this is my recipe")

my_recipe = recipe
my_recipe()

Explanation: my_recipe = recipe copies the function (not its result), and my_recipe() executes it. This is the foundation for decorators.

🧁 Step 2: Functions Inside Functions

You can define one function inside another. This lets you group logic and control scope.

def outer():
    def inner():
        print("I'm the inner function!")
    inner()

my_outer = outer
my_outer()

Explanation: inner() exists only within outer(). When you call outer(), it runs inner(). In this example, we assign outer to my_outer (as a function object), and then call it with my_outer(). This shows how nested functions can be executed from outside their definition block, and this nesting is key to how decorators work.

🧁 Step 3: Functions Returning Functions

Functions can return other functions—this lets us customize behavior dynamically.

def outer():
    def inner():
        print("Hello from inner!")
    return inner

my_func = outer()
my_func()

Explanation: outer() returns inner (not executed), and my_func() then executes it. This lets us create decorators that return a new function that wraps the original.

🧁 Step 4: Passing Functions to Functions

Functions can take other functions as arguments. These are often called callbacks.

def greet(func):
    print("Doing something first...")
    func()

def say_hi():
    print("Hi!")

greet(say_hi)

Explanation: We pass say_hi into greet, which then calls it. This is another essential idea behind decorators—they accept a function, modify its behavior, and return a new version.

🧁 Step 5: Making Your First Decorator!

This is the real deal. Here's your first decorator in action:

def my_decorator(func):
    def wrapper():
        print("Before the function runs")
        func()
        print("After the function runs")
    return wrapper

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

say_hello()

Explanation: The @my_decorator line means Python runs say_hello = my_decorator(say_hello) behind the scenes. This replaces say_hello with the wrapper function that calls the original one, with extra steps before and after.

say_hello = my_decorator(say_hello)
say_hello()

✨ Why Use Decorators?

  • Logging
  • Timing
  • Authentication
  • Validation
  • Keeping code DRY (Don’t Repeat Yourself)
Decorators are powerful tools for enhancing functions without modifying their internals.

🎥 Watch the Full Tutorial

Prefer to learn by watching? Check out the full step-by-step video tutorial on my YouTube channel:

Watch on YouTube →


#Python #Decorators #Beginners #Tutorial
Back to Blog