如何优化functools.partial动态模块属性的help显示格式?
优化动态生成partial属性的help显示格式
核心方案
用自定义包装类替代直接使用functools.partial,通过重写关键属性和方法,让help函数识别出符合预期的函数签名,同时保留原文档字符串。
实现代码
import functools class PartialWrapper: def __init__(self, func, name, *args, **kwargs): self.partial = functools.partial(func, *args, **kwargs) self.__name__ = name self.__doc__ = func.__doc__ # 继承原函数的文档字符串 def __call__(self, *args, **kwargs): return self.partial(*args, **kwargs) def __repr__(self): return f"{self.__name__}(*args, **kwargs)" # 模块fgb中的__getattr__实现示例 def __getattr__(name): # 根据实际业务逻辑调整可生成的属性列表 if name in ['crop', 'resize', 'blur']: return PartialWrapper(Filter, name) raise AttributeError(f"模块fgb没有属性'{name}'")
效果说明
- 调用
help(fgb.crop)时,签名会显示为crop(*args, **kwargs),不再出现partial相关标识 - 原Filter类的文档字符串会完整保留在help输出中
- 调用
fgb.crop(*args, **kwargs)的功能和之前直接用functools.partial完全一致
进阶优化(可选)
如果需要显示更精准的签名(匹配原Filter类的实际参数),可以借助inspect模块生成动态签名:
import functools import inspect class PartialWrapper: def __init__(self, func, name, *args, **kwargs): self.partial = functools.partial(func, *args, **kwargs) self.__name__ = name self.__doc__ = func.__doc__ # 获取原函数签名,剔除已绑定的参数 sig = inspect.signature(func) bound_args = sig.bind_partial(*args, **kwargs).arguments remaining_params = [p for p in sig.parameters.values() if p.name not in bound_args] self._signature = inspect.signature(lambda *args, **kwargs: None).replace(parameters=remaining_params) def __call__(self, *args, **kwargs): return self.partial(*args, **kwargs) def __repr__(self): return f"{self.__name__}{self._signature}"
比如原Filter类定义为Filter(width, height, mode='RGB'),当绑定width=100后,help会显示crop(height, mode='RGB'),更贴合实际可用参数。
内容的提问来源于stack exchange,提问作者kesh
相关产品推荐
相关产品推荐

