Python 中装饰器保持函数签名
为什么装饰器会丢失原函数的签名?如何使用 functools.wraps 或其他方式保持签名?
回答
小字辈
装饰器返回 wrapper 函数,其签名(参数列表、默认值等)与原函数不同。
from functools import wraps, partial
import inspect
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@my_decorator
def greet(name, greeting='Hello'):
pass
# wraps 可以恢复 __name__, __doc__
# 但不能恢复签名(参数信息)
print(inspect.signature(greet))
# (*args, **kwargs) <- 签名丢失
解决方案:
decorator库:from decorator import decorator,自动保持签名functools.partial:不会丢失签名- 手动设置
__signature__:
wrapper.__signature__ = inspect.signature(func)
inspect.signature() 对装饰器兼容性问题需要注意。