Decorators in Python

A decorator is a function that takes another function as input, adds extra functionality around it, and returns a new function - all without permanently modifying the original function's actual code.

Why Decorators Are Useful

Decorators let you add reusable behavior - like logging, timing, or access control - to multiple functions cleanly, without repeating the same extra code inside each one.

Writing a Simple Decorator

def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Finished: {func.__name__}")
        return result
    return wrapper

@log_call
def add(a, b):
    return a + b

add(3, 5)

The @log_call line above the function definition is shorthand for writing add = log_call(add). Every time add() is called, it now automatically runs the extra logging logic wrapped around it.

A Practical Example: Timing a Function

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} took {time.time() - start:.4f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()
Decorators are used extensively in real-world Python frameworks - for example, web frameworks like Flask use decorators like @app.route() to connect URLs to functions.

Coming Up Next

Next, the course takes a step back to cover the four core principles that define Object Oriented Programming as a whole.

Ready to Master Data Science?

Join Uncodemy's Data Science Course and build real, job-ready skills with expert mentors.

Explore Course