close-up-hand-holding-futuristic-screen

Python Decorators Explained with Examples and Interview Questions

Python decorators are one of the most powerful features of the language. They allow you to modify the behavior of a function or class without changing its code. If you’ve ever used @staticmethod, @classmethod, or @property, you’ve already used a decorator.

In this article, we’ll cover:

  • What decorators are in Python

  • How to write your own decorators

  • Real-world examples of decorators

  • Common interview questions on Python decorators


What is a Decorator in Python?

A decorator in Python is simply a function that takes another function as input and extends or modifies its behavior without explicitly changing its code.

They use the “@” syntax sugar and are commonly applied above function definitions.


A Simple Decorator Example

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

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

say_hello()

Output:

Before function runs
Hello, World!
After function runs

Here’s what happens:

  1. @my_decorator wraps the function say_hello.

  2. When you call say_hello(), you are actually calling the wrapper() inside the decorator.

  3. This lets you add behavior before and after the function execution.


Decorators with Arguments

Sometimes you want your decorator to accept arguments.

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello {name}")

greet("Alice")

 

Output:

Hello Alice
Hello Alice
Hello Alice

Here, the decorator repeats the function call n times.


Real-World Examples of Decorators

1. Logging

def log(func):
    def wrapper(*args, **kwargs):
        print(f"Function {func.__name__} called with arguments {args}, {kwargs}")
        return func(*args, **kwargs)
    return wrapper

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

print(add(5, 3))

Output:

Function add called with arguments (5, 3), {}
8

2. Authorization

def require_admin(func):
    def wrapper(user, *args, **kwargs):
        if user != "admin":
            print("Access denied")
            return
        return func(user, *args, **kwargs)
    return wrapper

@require_admin
def delete_account(user, account_id):
    print(f"Account {account_id} deleted by {user}")

delete_account("guest", 123)   # Access denied
delete_account("admin", 123)   # Account 123 deleted by admin

3. Timing Function Execution

import time

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

@timer
def slow_function():
    time.sleep(2)
    print("Finished")

slow_function()

Built-in Decorators in Python

Python provides some useful decorators out of the box:

  • @staticmethod – Defines a static method in a class

  • @classmethod – Defines a class-level method

  • @property – Defines a method as a property

Example:

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @staticmethod
    def pi():
        return 3.14159

c = Circle(5)
print(c.radius)  # 5
print(Circle.pi())  # 3.14159

Interview Questions on Python Decorators

Here are some common Python interview questions related to decorators:

  1. What is a decorator in Python and why is it used?
    → A decorator is a function that modifies another function without changing its source code. It is used for logging, authentication, performance measurement, caching, etc.

  2. How do you write a decorator that accepts arguments?
    → You create a function that returns a decorator function, which in turn returns a wrapper.

  3. What’s the difference between @staticmethod, @classmethod, and @property?

    • @staticmethod: method doesn’t use self or cls.

    • @classmethod: method takes cls as first argument.

    • @property: turns a method into a read-only property.

  4. Can a decorator be applied to a class?
    → Yes. A class decorator takes a class as input and modifies it.

  5. What is functools.wraps and why is it used in decorators?
    functools.wraps is used inside decorators to preserve the original function’s name, docstring, and metadata. Without it, the wrapper function replaces them.


Final Thoughts

Decorators are a powerful Python feature that allow cleaner, reusable, and modular code. Whether you’re building logging utilities, enforcing access control, caching results, or timing functions, decorators provide a neat solution.

For interviews, make sure you can:

  • Explain what a decorator is

  • Write a simple decorator from scratch

  • Explain the difference between built-in decorators


Key Takeaways

  • Python decorators let you modify function behavior without changing code.

  • Use decorators for logging, authentication, performance monitoring, and caching.

  • Know the difference between @staticmethod, @classmethod, and @property.

  • Interviewers often test your ability to write custom decorators.

Related Articles