Understanding Python Decorators: A Beginner's Tutorial

Python Logo

A decorator in Python is a design pattern that allows you to add new functionality to an existing object (like a function) without modifying its structure. Decorators are a form of metaprogramming and are heavily used in popular Python frameworks.

Functions are First-Class Objects

To understand decorators, you must first understand that functions in Python can be passed as arguments to other functions and returned from them.

A Simple Decorator

A decorator is essentially a function that takes another function as an argument, wraps it in an inner function to add functionality, and returns the wrapper function.

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

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

# The 'decorated' way
say_hello = my_decorator(say_hello)
say_hello()

The `@` Syntactic Sugar

Python provides a much cleaner syntax for applying decorators using the `@` symbol.

@my_decorator
def say_whee():
    print("Whee!")

say_whee()

A Practical Example: A Timer Decorator

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} ran in: {end_time - start_time:.4f} sec")
        return result
    return wrapper

@timer
def long_running_function():
    time.sleep(2)

long_running_function()

Comments