Decorators in Python
Overview
This lesson covers decorators in Python, a powerful feature that allows you to modify the behavior of functions or methods. Understanding decorators can greatly enhance your ability to write readable, efficient, and elegant Python code.
Introduction
A decorator in Python is a function that takes another function as an argument, adds some kind of functionality or modification to the input function, and returns a modified function. Decorators provide a flexible way to extend the behavior of functions without permanently modifying them.
Basic Concept
- Decorator Syntax: In Python, decorators are applied to functions using the
@symbol followed by the decorator function name before the function definition.
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!")
How Decorators Work
- When you decorate a function with
@my_decorator, you’re essentially saying, “Applymy_decoratortosay_hello.” - The
say_hellofunction is passed tomy_decoratoras an argument (func), and thewrapperfunction adds behavior before and after callingsay_hellowithin it.
Using Decorators
- With Arguments: If the original function takes arguments, the wrapper function must also take those arguments (or use
*argsand**kwargsto accept an arbitrary number of arguments).
def decorator_with_args(func):
def wrapper(*args, **kwargs):
print("Something before the original function is called.")
result = func(*args, **kwargs)
print("Something after the original function is called.")
return result
return wrapper
Built-in Decorators
- Python includes several built-in decorators, like
@staticmethod,@classmethod, and@property, which are commonly used in object-oriented programming.
Chaining Decorators
- Decorators can be stacked, allowing you to apply multiple modifications to a function.
@decorator_one
@decorator_two
def my_function():
pass
Practical Uses
- Logging: Use decorators to log when a function is called.
- Timing: Measure how long a function takes to execute.
- Authorization: Check if a user has permission to execute a function.
- Caching/Memoization: Store the results of expensive function calls and return the cached result when the same inputs occur again.
Conclusion
Decorators are a significant part of Python’s expressive power, allowing for concise, readable, and efficient code. By mastering decorators, you can write code that is more modular, reusable, and easy to change or extend.
Additional Resources
- Python’s functools.wraps: A helper for decorator-making that preserves the metadata of the original function.
- Real Python - Primer on Python Decorators: Comprehensive guide on decorators with examples.