Home >Backend Development >Python Tutorial >What are decorators in Python? How do you create one?
Decorators in Python are a powerful and elegant way to modify or enhance the behavior of functions or classes without directly changing their source code. They are essentially functions that take another function as an argument and extend or alter its behavior. Decorators allow you to wrap another function in order to execute code before and after the wrapped function runs.
To create a decorator, you can follow these steps:
Here is an example of how to create a simple decorator:
<code class="python">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()</code>
In this example, my_decorator
is the decorator, and say_hello
is the function being decorated. When say_hello
is called, it will execute the code within the wrapper
function.
Decorators provide several key benefits in Python programming:
@decorator
syntax is clear and concise, making the code easier to read and understand.Decorators can be used to modify the behavior of functions in various ways. Here are some common applications:
Logging: Decorators can log function calls, inputs, outputs, and execution times for debugging and monitoring purposes.
<code class="python">def log_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}") result = func(*args, **kwargs) print(f"{func.__name__} finished execution") return result return wrapper @log_decorator def add(a, b): return a b</code>
Timing: You can use decorators to measure the execution time of functions, which is useful for performance optimization.
<code class="python">import time def timer_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"{func.__name__} took {end_time - start_time} seconds to run.") return result return wrapper @timer_decorator def slow_function(): time.sleep(2) print("Slow function executed")</code>
Authentication and Authorization: Decorators can be used to check if a user is authenticated before allowing access to certain functions.
<code class="python">def requires_auth(func): def wrapper(*args, **kwargs): if not authenticated: raise PermissionError("Authentication required") return func(*args, **kwargs) return wrapper @requires_auth def protected_function(): print("This function is protected")</code>
Memoization: Decorators can cache the results of expensive function calls to improve performance.
<code class="python">def memoize(func): cache = {} def wrapper(*args): if args in cache: return cache[args] result = func(*args) cache[args] = result return result return wrapper @memoize def fibonacci(n): if n </code>
Let's consider a practical example of implementing a decorator for caching results, which can significantly improve the performance of computationally expensive functions. We'll use a Fibonacci function to demonstrate this:
<code class="python">def memoize(func): cache = {} def wrapper(*args): if args in cache: print(f"Returning cached result for {args}") return cache[args] result = func(*args) cache[args] = result print(f"Caching result for {args}") return result return wrapper @memoize def fibonacci(n): if n </code>
In this example:
memoize
decorator maintains a dictionary cache
to store the results of function calls. The wrapper
function checks if the result for a given set of arguments is already in the cache. If it is, it returns the cached result; otherwise, it computes the result, caches it, and then returns it.fibonacci
function calculates Fibonacci numbers recursively. Without memoization, this would lead to many redundant calculations, especially for larger numbers. The @memoize
decorator applied to fibonacci
ensures that each Fibonacci number is calculated only once and reused for subsequent calls.fibonacci(10)
is first called, the decorator will compute and cache the result. On the second call to fibonacci(10)
, it will retrieve the result from the cache, demonstrating the performance improvement.This example illustrates how decorators can be used to enhance the performance of functions by implementing memoization, which is a common technique in optimization and dynamic programming scenarios.
The above is the detailed content of What are decorators in Python? How do you create one?. For more information, please follow other related articles on the PHP Chinese website!