Before After 装饰器 触发

5 min read Oct 02, 2024
Before After 装饰器 触发

Understanding Decorators: Before and After Functions in Python

Decorators are a powerful feature in Python that allow you to modify the behavior of functions without directly changing their code. Imagine having a set of actions you want to perform before and after a particular function call. Decorators provide a clean and elegant way to achieve this.

What are Decorators?

In essence, decorators are functions that take another function as an argument and return a modified version of that function. This modification can include adding functionalities like logging, timing, or authentication before and after the original function's execution.

The "Before and After" Scenario

Let's say you have a function that performs a calculation, and you want to track the time it takes to complete this calculation. Instead of adding the timing logic directly into the calculation function, you can use a decorator.

Here's a simple example of a decorator that prints a message "Starting calculation" before the function executes and "Calculation finished" after the function completes:

def my_decorator(func):
  def wrapper(*args, **kwargs):
    print("**Starting calculation**")
    result = func(*args, **kwargs)
    print("**Calculation finished**")
    return result
  return wrapper

@my_decorator
def calculate_sum(a, b):
  return a + b

result = calculate_sum(5, 10)
print("Result:", result)

In this code:

  • my_decorator is the decorator function.
  • wrapper is a nested function that will be called when the decorated function (calculate_sum) is executed.
  • @my_decorator syntax is a shorthand for applying the decorator to calculate_sum.

The output of this code would be:

**Starting calculation**
**Calculation finished**
Result: 15

Advantages of Using Decorators

  • Clean and Modular Code: Decorators keep your core function logic separate from the extra functionalities.
  • Reusability: You can apply the same decorator to multiple functions.
  • Readability: The @decorator_name syntax makes the code more readable and self-explanatory.

Exploring Decorators with functools.wraps

While the above example works, it has a small drawback. When you inspect the decorated function's properties, you might notice that the name and docstring are replaced with those of the wrapper function. To overcome this, you can use functools.wraps.

from functools import wraps

def my_decorator(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    print("**Starting calculation**")
    result = func(*args, **kwargs)
    print("**Calculation finished**")
    return result
  return wrapper

@my_decorator
def calculate_sum(a, b):
  """Calculates the sum of two numbers."""
  return a + b

print(calculate_sum.__name__)  # Output: calculate_sum
print(calculate_sum.__doc__)  # Output: Calculates the sum of two numbers.

Real-world Applications of Decorators

Here are some common scenarios where decorators shine:

  • Logging: Logging function calls, parameters, and return values.
  • Timing: Measuring the execution time of functions.
  • Caching: Storing function results to speed up subsequent calls.
  • Authentication: Checking user permissions before allowing function execution.
  • Error Handling: Handling potential errors gracefully.

Conclusion

Decorators provide a powerful and elegant way to extend function behavior in Python without modifying the original function's code. By using decorators, you can achieve code modularity, reusability, and cleaner syntax. Remember, decorators are a valuable tool for building more robust and maintainable Python applications.

Featured Posts