一.介绍
在本文中,我们将了解 @wraps。在 Python 中使用装饰器时,您可能会遇到原始函数的元数据丢失的情况。这时,functools 模块中的 @wraps 装饰器就可以派上用场了。让我们深入了解 @wraps 的作用及其重要性。
二.简单装饰器的问题
首先,让我们看一个不使用@wraps的简单装饰器。
def my_decorator(func):
def wrapper(args, kwargs):
print("Something is happening before the function is called.")
result = func(args, kwargs)
print("Something is happening after the function is called.")
return result
return wrapper
@my_decorator
def say_hello(name):
"""This function greets a person by name."""
print(f"Hello, {name}!")
print(say_hello.__name__)
print(say_hello.__doc__)
如果您运行上述代码,您将看到以下输出。
wrapper
None
问题在于,我们原来的 say_hello 函数的名称和文档已被包装函数覆盖。这可能会导致调试、自省和文档方面的问题。
三.使用 @wraps
现在,让我们使用@wraps 修改我们的装饰器。
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(args, kwargs):
print("Something is happening before the function is called.")
result = func(args, kwargs)
print("Something is happening after the function is called.")
return result
return wrapper
@my_decorator
def say_hello(name):
"""This function greets a person by name."""
print(f"Hello, {name}!")
print(say_hello.__name__)
print(say_hello.__doc__)
现在,当您运行上述代码时,您将获得低于 O/P 的结果。
say_hello:
This function greets a person by name.
四.@wraps 正在工作
@wraps 本身是一个装饰器,它更新包装函数,使其看起来像包装函数。它通过将几个属性从原始函数复制到包装函数来实现这一点,包括:
- 姓名
- 文档
- 模块
- 注释
- 限定名称
通过保留这些属性,@wraps 可确保原始函数的元数据在装饰时不会丢失。
五.为什么要使用@wraps?
编写装饰器时使用@wraps 被认为是最佳实践,因为。
- 它维护准确的功能元数据,这对于文档工具和 IDE 至关重要。
- 它通过保留原始函数的名称和文档字符串来帮助调试。
- 它允许更好地反省装饰函数。
六.概括
@wraps 装饰器是 Python 中一个简单但功能强大的工具,它有助于在使用装饰器时维护函数元数据的完整性。通过将 @wraps 合并到装饰器中,您可以确保代码保持更易读、更易于调试和更易于维护。