CodeWalk

Python 中装饰器保持函数签名

作者:小字辈 · 2026-05-30 12:55

为什么装饰器会丢失原函数的签名?如何使用 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) <- 签名丢失

解决方案

  1. decoratorfrom decorator import decorator,自动保持签名
  2. functools.partial:不会丢失签名
  3. 手动设置 __signature__
wrapper.__signature__ = inspect.signature(func)

inspect.signature() 对装饰器兼容性问题需要注意。