DEV Community

Lameck Odhiambo
Lameck Odhiambo

Posted on

Decorators in Python

Decorators in Python allow you to dynamically inject new functionality into a function without altering its internal logic. This powerful metaprogramming technique promotes clean, modular code by letting you reuse standard utilities like logging, authentication, and caching across multiple functions.

Basic decorator structure:

def my_decorator(func):
    def wrapper():
        print("Something is happening BEFORE the function is called.")
        func()  # Call the original function
        print("Something is happening AFTER the function is called.")
    return wrapper

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

say_hello()
Enter fullscreen mode Exit fullscreen mode

Output:

Something is happening BEFORE the function is called.
Hello!
Something is happening AFTER the function is called.
Enter fullscreen mode Exit fullscreen mode
  • If the function you are decorating accepts arguments, your inner wrapper function must be built to accept and pass them through using *args and **kwargs. This ensures your decorator remains flexible and can work on any function.
def log_arguments(func):
    def wrapper(*args, **kwargs):
        print(Log: Function '{func.__name__}' was called with inputs: {args} {kwargs}")
        return func(*args, **kwargs)  # Capture and return the original function's result
    return wrapper

@log_arguments
def add_numbers(a, b):
    return a + b

result = add_numbers(5, 10)
Enter fullscreen mode Exit fullscreen mode

Real world application of Decorators

def pandas_decorator(fx):

    def mainfunc(*args):
        response = fx(*args)
        # Do some pandas specific processing here
        response.to_parquet("Ch-3_Polymorphism&Decorators\\temp.parquet")
        return response

    return mainfunc

@pandas_decorator
def csv_to_parquet(file_path:str):
    import pandas as pd
    df = pd.read_csv(file_path)
    return df


response = csv_to_parquet("Ch-3_Polymorphism&Decorators\\orders.csv")
print(response.head())
Enter fullscreen mode Exit fullscreen mode
  • This code demonstrates how Python decorators can be used to add extra functionality to an existing function without changing its original logic. The pandas_decorator(fx) function takes another function as an argument, while its inner function, mainfunc(*args), accepts the arguments passed to the original function and executes it using fx(*args). The returned result is stored in response, which is a Pandas DataFrame. The decorator then uses response.to_parquet() to save the DataFrame as a Parquet file named temp.parquet before returning the DataFrame. The @pandas_decorator syntax applies this decorator to the csv_to_parquet() function, which uses pd.read_csv(file_path) to load data from orders.csv. Finally, response = csv_to_parquet(...) executes the decorated function, reads the CSV file, saves the data as Parquet, and returns the DataFrame, while print(response.head()) displays its first five rows. In summary, the decorator automates saving the DataFrame to Parquet while allowing the original function to continue returning the data for further analysis.

Top comments (0)