logologo
  • AI Tools

    DB Query GeneratorMock InterviewResume BuilderLearning Path GeneratorCheatsheet GeneratorAgentic Prompt GeneratorCompany ResearchCover Letter Generator
  • XpertoAI
  • MVP Ready
  • Resources

    CertificationsTopicsExpertsCollectionsArticlesQuestionsVideosJobs
logologo

Elevate Your Coding with our comprehensive articles and niche collections.

Useful Links

  • Contact Us
  • Privacy Policy
  • Terms & Conditions
  • Refund & Cancellation
  • About Us

Resources

  • Xperto-AI
  • Certifications
  • Python
  • GenAI
  • Machine Learning

Interviews

  • DSA
  • System Design
  • Design Patterns
  • Frontend System Design
  • ReactJS

Procodebase © 2024. All rights reserved.

Level Up Your Skills with Xperto-AI

A multi-AI agent platform that helps you level up your development skills and ace your interview preparation to secure your dream job.

Launch Xperto-AI

Decorators in Python

author
Generated by
ProCodebase AI

13/01/2025

Python

Sign in to read full article

Introduction to Decorators

In Python, decorators are a powerful construct that allows you to wrap functions or methods to extend their behavior without modifying their structure. Think of decorators as wrappers that add functionality to an existing piece of code, enhancing its behavior. This not only makes code cleaner but also aligns with the principles of DRY (Don't Repeat Yourself) programming.

Let's start with a simple example to illustrate how decorators work.

A Basic Decorator

def my_decorator(func): def wrapper(): print("Something is happening before the function is called.") func() print("Something is happening after the function is called.") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello()

When you run this code, the output will be:

Something is happening before the function is called.
Hello!
Something is happening after the function is called.

The @my_decorator syntax is a shorthand for say_hello = my_decorator(say_hello), wrapping the say_hello function with additional code.

Decorators with Arguments

Sometimes, you may want your decorator to accept arguments themselves. This means you need an extra level of nesting.

Example of a Decorator with Arguments

def repeat(num_times): def decorator_repeat(func): def wrapper(*args, **kwargs): for _ in range(num_times): func(*args, **kwargs) return wrapper return decorator_repeat @repeat(3) def greet(name): print(f"Hello, {name}!") greet("Alice")

Output:

Hello, Alice!
Hello, Alice!
Hello, Alice!

In this example, the repeat function takes a parameter num_times, which allows us to control how many times the greet function is executed.

Using functools.wraps in Decorators

When creating decorators, it is crucial to maintain the original function’s metadata (like its name and docstring). Python provides a utility called functools.wraps for this purpose.

Here’s how we can incorporate it:

from functools import wraps def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): print("Before function call.") result = func(*args, **kwargs) print("After function call.") return result return wrapper @my_decorator def example_function(): """This is an example function.""" print("Executing example function.") print(example_function.__name__) # Outputs: example_function print(example_function.__doc__) # Outputs: This is an example function.

Using @wraps(func) preserves the original function’s metadata, making debugging and documentation easier.

Class Decorators

Decorators don’t just work with functions; they can also be applied to classes. Here’s an example demonstrating how decorators can modify a class’s behavior:

def add_str_method(cls): cls.__str__ = lambda self: f"{self.__class__.__name__} instance" return cls @add_str_method class MyClass: pass obj = MyClass() print(str(obj)) # Outputs: MyClass instance

In this case, the add_str_method decorator adds a __str__ method to MyClass, customizing how instances are represented as strings.

Chaining Decorators

You can apply multiple decorators to a single function, which allows you to stack behaviors.

Example of Chaining Decorators

def decorator_one(func): @wraps(func) def wrapper(*args, **kwargs): print("Decorator One: Before function call.") return func(*args, **kwargs) return wrapper def decorator_two(func): @wraps(func) def wrapper(*args, **kwargs): print("Decorator Two: Before function call.") return func(*args, **kwargs) return wrapper @decorator_one @decorator_two def say_bye(): print("Goodbye!") say_bye()

Output:

Decorator One: Before function call.
Decorator Two: Before function call.
Goodbye!

In this example, when say_bye() is called, both decorators are applied in the order they are listed.

Practical Use Cases of Decorators

  1. Logging: Adding logging functionality to track the execution flow and variable values in functions.
  2. Authorization: Controlling access to certain functions, especially useful in web applications.
  3. Caching: Storing results of expensive function calls and returning the cached result when the same inputs occur again.

Example: Caching with a Decorator

Here’s a simple caching decorator:

def cache(func): memo = {} @wraps(func) def wrapper(*args): if args in memo: return memo[args] result = func(*args) memo[args] = result return result return wrapper @cache def fibonacci(n): if n < 2: return n return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(10)) # Outputs: 55

This decorator cache stores previous results of the fibonacci function, significantly improving performance for larger inputs.

Conclusion

Mastering decorators opens a world of possibilities in Python programming. They not only provide a way to augment existing functions but also help maintain cleaner and more maintainable code. By exploring advanced patterns such as decorators with arguments, class decorators, and caching mechanisms, you can leverage their power to write efficient and elegant code in your Python projects. As you continue to enhance your skills, consider implementing these patterns wherever applicable to make your coding experience more enjoyable.

Popular Tags

PythonDecoratorsAdvanced Python

Share now!

Like & Bookmark!

Related Collections

  • Python Basics: Comprehensive Guide

    21/09/2024 | Python

  • LangChain Mastery: From Basics to Advanced

    26/10/2024 | Python

  • Mastering NLP with spaCy

    22/11/2024 | Python

  • PyTorch Mastery: From Basics to Advanced

    14/11/2024 | Python

  • Matplotlib Mastery: From Plots to Pro Visualizations

    05/10/2024 | Python

Related Articles

  • Named Entity Recognition with NLTK in Python

    22/11/2024 | Python

  • Understanding Context Managers in Python

    13/01/2025 | Python

  • Mastering File Handling in Python

    21/09/2024 | Python

  • N-Gram Models for Text Analysis in Python

    22/11/2024 | Python

  • Threading and Concurrency in Python

    13/01/2025 | Python

  • Advanced Exception Handling Techniques in Python

    13/01/2025 | Python

  • Image Stitching with Python and OpenCV

    06/12/2024 | Python

Popular Category

  • Python
  • Generative AI
  • Machine Learning
  • ReactJS
  • System Design