DEV Community

Samita Khanduri
Samita Khanduri

Posted on

Understanding Python Decorators: A Beginner’s Guide with Examples

Understanding Python Decorators: A Beginner’s Guide with Examples

Python decorators are a powerful and versatile tool for modifying the behavior of functions or methods. They allow you to add functionality to existing code without altering its structure. In this article, we’ll break down decorators and provide simple examples to help you understand and use them effectively.


What are Decorators?

A decorator in Python is essentially a function that takes another function as an argument and extends or alters its behavior. Decorators are commonly used to add features like logging, access control, memoization, or validation to existing functions or methods.

Decorators in Python are applied using the @decorator_name syntax placed above the function definition.


Anatomy of a Decorator

A basic decorator function has the following structure:

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        # Code to execute before the original function
        result = original_function(*args, **kwargs)
        # Code to execute after the original function
        return result
    return wrapper_function
Enter fullscreen mode Exit fullscreen mode

Applying a Decorator

You can apply a decorator to a function using the @decorator_name syntax or manually:

@decorator_function
def some_function():
    print("This is the original function.")

# Equivalent to:
# some_function = decorator_function(some_function)
Enter fullscreen mode Exit fullscreen mode

Example 1: A Basic Decorator

Let’s create a simple decorator that prints a message before and after a function runs.

def simple_decorator(func):
    def wrapper():
        print("Before the function call.")
        func()
        print("After the function call.")
    return wrapper

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

say_hello()
Enter fullscreen mode Exit fullscreen mode

Output:

Before the function call.
Hello, World!
After the function call.
Enter fullscreen mode Exit fullscreen mode

Example 2: A Decorator with Arguments

You can create a decorator that accepts arguments by wrapping it in another function.

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

@repeat_decorator(3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")
Enter fullscreen mode Exit fullscreen mode

Output:

Hello, Alice!
Hello, Alice!
Hello, Alice!
Enter fullscreen mode Exit fullscreen mode

Real-Life Applications of Decorators

Decorators are extensively used in real-world scenarios. Here are some simplified practical examples:

1. Logging User Actions

You can use a decorator to log every time a user performs an action.

def log_action(func):
    def wrapper(*args, **kwargs):
        print(f"Action: {func.__name__} is being performed.")
        return func(*args, **kwargs)
    return wrapper

@log_action
def upload_file(filename):
    print(f"Uploading {filename}...")

upload_file("report.pdf")
Enter fullscreen mode Exit fullscreen mode

Output:

Action: upload_file is being performed.
Uploading report.pdf...
Enter fullscreen mode Exit fullscreen mode

2. Tracking Execution Time

Track how long tasks take to execute, useful for performance monitoring.

import time

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

@track_time
def download_file(file_size):
    time.sleep(file_size / 10)  # Simulate download time
    print("Download complete.")

download_file(50)
Enter fullscreen mode Exit fullscreen mode

Output:

Download complete.
download_file took 5.00 seconds to execute.
Enter fullscreen mode Exit fullscreen mode

3. Adding User Greetings

A decorator can personalize greetings by adding dynamic elements.

def add_greeting(func):
    def wrapper(name):
        print("Hello, welcome!")
        func(name)
    return wrapper

@add_greeting
def show_user_profile(name):
    print(f"User Profile: {name}")

show_user_profile("Alice")
Enter fullscreen mode Exit fullscreen mode

Output:

Hello, welcome!
User Profile: Alice
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Decorators are a powerful way to modify the behavior of functions or methods.
  • They can simplify repetitive tasks like logging, timing, or personalization.
  • Use the @decorator syntax to apply them conveniently.
  • Decorators can accept arguments and be nested for added flexibility.

By mastering decorators, you’ll unlock a valuable tool for writing clean and efficient Python code. Start experimenting with the examples provided to get comfortable with this concept!

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more