如何使用functools.wraps适配固定推导参数的包装函数参数说明
解决方案
下面提供两种生产环境常用的实现方式,可根据场景选择:
方案1:动态修改函数签名(IDE提示最友好)
通过inspect标准库修改g的公开签名,去掉自动推导的参数b,同时继承f的所有元信息和文档。该方案对help()查询、IDE自动补全都完全生效,用户调用g时不会看到参数b的提示,感知效果完全符合要求。
代码示例:
import inspect from functools import wraps def deduce(a): # 你的推导逻辑示例 return a * 2 def f(a, b, c, d, e): """f函数的原始文档说明 :param a: 参数a的说明 :param b: 参数b的说明 :param c: 参数c的说明 :param d: 参数d的说明 :param e: 参数e的说明 """ return a + b + c + d + e @wraps(f) def g(a, **kwargs): # 可选:防止用户误传参数b if 'b' in kwargs: raise ValueError("参数b不可手动传入,将根据a自动推导") b = deduce(a) return f(a, b, **kwargs) # 动态修改g的签名,去掉参数b sig = inspect.signature(f) params = list(sig.parameters.values()) # 过滤掉参数b new_params = [p for p in params if p.name != 'b'] # 重新赋值签名 g.__signature__ = sig.replace(parameters=new_params) # 可选:在文档开头追加说明 g.__doc__ = "注意:参数`b`会根据传入的`a`自动推导,无需手动传入,其余参数规则与`f`完全一致\n\n" + g.__doc__
验证效果:调用help(g)时会显示去掉b的参数列表,且包含追加的说明,主流IDE(Pycharm、VSCode等)输入g(时也只会提示a, c, d, e四个参数。
方案2:手动修改文档(兼容性最优)
如果不需要IDE自动补全适配,只需要让用户查看文档时明确规则,可直接在wraps基础上修改文档说明,适配所有Python版本:
from functools import wraps def g(a, **kwargs): """ 注意:本函数为`f`的封装,参数`b`会根据传入的`a`自动推导,无需手动传入,其余参数规则与`f`完全一致。 """ b = deduce(a) return f(a, b, **kwargs) # 继承f的元信息 g.__name__ = f.__name__ g.__doc__ += f"\n\n原函数`f`的文档:\n{f.__doc__}"
内容的提问来源于stack exchange,提问作者noctilux
相关产品推荐
相关产品推荐

