You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python装饰器内部设置函数__signature__属性不生效问题咨询

你代码的问题出在属性赋值顺序和__dict__的覆写操作上,不是Python的bug。

原因解释

  1. 你先给new_function设置了__signature__属性,这个自定义属性会存储在new_function.__dict__字典中。
  2. 随后你执行了new_function.__dict__ = getattr(func, '__dict__', None),这行是直接用原函数的__dict__完全覆盖了新函数的__dict__,之前写入的__signature__属性直接被清空了,自然会报AttributeError,inspect.signature读不到自定义签名就会 fallback 到新函数本身的*args, **kwargs签名。
  3. 你全局测试的代码没有覆写目标函数的__dict__,所以设置的__signature__可以正常保留,符合预期。

修复方案

方案1:调整属性赋值顺序,先处理__dict__再设置自定义属性

import inspect

def decorator(func):
    def new_function(*args, **kwargs):
        return func(*args, **kwargs)
    # 先处理__dict__覆写,再设置其他自定义属性
    new_function.__dict__ = getattr(func, '__dict__', {})
    new_function.__signature__ = inspect.signature(func)
    new_function.__name__ = "test __name__"
    new_function.__doc__ = "test __doc__"
    new_function.__qualname__ = "test __qualname__"
    new_function.__kwdefaults__ = getattr(func, '__kwdefaults__', None)
    return new_function

方案2:合并而非覆写__dict__,保留已有自定义属性

import inspect

def decorator(func):
    def new_function(*args, **kwargs):
        return func(*args, **kwargs)
    new_function.__signature__ = inspect.signature(func)
    new_function.__name__ = "test __name__"
    new_function.__doc__ = "test __doc__"
    new_function.__qualname__ = "test __qualname__"
    new_function.__kwdefaults__ = getattr(func, '__kwdefaults__', None)
    # 用update合并原函数的自定义属性,不会覆盖已有的属性
    new_function.__dict__.update(getattr(func, '__dict__', {}))
    return new_function

方案3:直接使用标准库functools.wraps处理元信息复制,避免手动踩坑

标准库的functools.wraps已经封装了所有函数元信息(包括__signature__、__annotations__、__kwdefaults__等)的复制逻辑,不需要手动逐个赋值,如果你需要自定义部分元信息,只需要在wraps之后覆盖对应属性即可:

import inspect
import functools

def decorator(func):
    @functools.wraps(func)
    def new_function(*args, **kwargs):
        return func(*args, **kwargs)
    # 自定义覆盖需要修改的元信息
    new_function.__name__ = "test __name__"
    new_function.__doc__ = "test __doc__"
    new_function.__qualname__ = "test __qualname__"
    return new_function

内容的提问来源于stack exchange,提问作者winwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:15:00