Creating a Class-Based Decorator for Logging Execution Time in Python

A structured approach to measure and monitor method performance using decorators

Introduction

In Python, decorators are a powerful feature that allows developers to modify or enhance the behavior of functions or methods without altering their actual code. They are commonly used for logging, authentication, validation, and performance monitoring. While function-based decorators are widely used, class-based decorators offer a cleaner, more extensible design—especially when the decorator requires state management or additional logic. A common scenario in application development is measuring how long a method takes to execute. By creating a class-based decorator, we can easily track execution times across multiple functions, ensuring that our application remains efficient and bottlenecks are identified.

Master Python: 600+ Real Coding Interview Questions
Master Python: 600+ Real Coding Interview Questions

A class-based decorator works by defining a class that implements the __init__ and __call__ methods.

  1. The __init__ Method
    • This method is called once when the decorator is applied.
    • It typically stores the reference to the function being decorated.
  2. The __call__ Method
    • This method makes the class instance callable, just like a function.
    • It is triggered when the decorated function is executed.
    • Here, we can insert logic to measure the execution time before and after calling the actual function.

For execution time measurement, we can use Python’s built-in time module. The workflow looks like this:

  • Record the start time.
  • Execute the original function.
  • Record the end time.
  • Compute and log the difference as execution time.
Machine Learning & Data Science 600+ Real Interview Questions
Machine Learning & Data Science 600 Real Interview Questions

Here’s a simple implementation:

import time

class LogExecutionTime:
    def __init__(self, func):
        self.func = func  # store the decorated function

    def __call__(self, *args, **kwargs):
        start_time = time.time()
        result = self.func(*args, **kwargs)  # execute the function
        end_time = time.time()
        execution_time = end_time - start_time
        print(f"Execution time of {self.func.__name__}: {execution_time:.4f} seconds")
        return result

# Example usage
@LogExecutionTime
def sample_method():
    time.sleep(2)
    print("Method finished.")

sample_method()

When sample_method is called, the decorator logs its execution time without modifying the function’s actual code. This approach is reusable and can be applied to any function in your application.

Master LLM and Gen AI: 600+ Real Interview Questions
Master LLM and Gen AI: 600+ Real Interview Questions

Conclusion

In conclusion, creating a class-based decorator for logging execution time in Python provides a structured and reusable way to monitor performance. By implementing the __init__ and __call__ methods, we can wrap any function with timing logic, ensuring minimal code duplication and maximum clarity. This design is especially useful in larger applications where consistent logging is required across multiple methods. Ultimately, class-based decorators make Python applications more maintainable and efficient by combining object-oriented principles with the flexibility of decorators.


Leave a Reply