Python类中无冗余代码/docstring的方法属性转发重定向最优方案
解决方案
1. 自动实现方法调用转发
方案一:使用__getattr__魔法方法(最简实现)
Python 中对象的属性/方法查找优先级里,__getattr__会在类本身没有对应属性时触发,刚好可以用来做自动转发:
class Foo: def __init__(self, bar: Bar): self.bar = bar def __getattr__(self, method_name): # 所有Foo类未定义的方法,都会转发给self.bar的对应方法 return getattr(self.bar, method_name)
如果需要限制可转发的方法范围,避免暴露内部方法,可加白名单控制:
class Foo: # 允许对外暴露的Bar类方法列表 _ALLOWED_FORWARD_METHODS = {"name", "run", "get_config"} def __init__(self, bar: Bar): self.bar = bar def __getattr__(self, method_name): if method_name in self._ALLOWED_FORWARD_METHODS: return getattr(self.bar, method_name) raise AttributeError(f"'Foo' object has no attribute '{method_name}'")
注意:该方案运行时调用完全正常,但IDE的类型提示、docstring预览可能不生效,对开发体验有要求可以看第二种方案。
方案二:动态批量绑定方法(支持类型提示+docstring同步)
如果需要兼容IDE提示,可以在类定义完成后批量生成转发方法,不需要手动逐个定义:
from functools import wraps class Foo: _FORWARD_TO_BAR = {"name", "run", "get_config"} def __init__(self, bar: Bar): self.bar = bar # 批量生成转发方法 for method_name in Foo._FORWARD_TO_BAR: original_func = getattr(Bar, method_name) @wraps(original_func) def wrapper(self, *args, __method_name=method_name, **kwargs): return getattr(self.bar, __method_name)(*args, **kwargs) setattr(Foo, method_name, wrapper)
2. 自动同步docstring
上面方案二已经天然解决了docstring同步的问题:functools.wraps装饰器会自动把原方法的__doc__、__name__、注解等元信息全部复制到转发方法上,不需要做任何额外操作,运行时调用help(Foo.name)、IDE预览docstring都可以正常显示Bar类对应方法的文档内容。
如果只需要同步少量方法,也可以用装饰器手动标记,不需要批量生成:
from functools import wraps def forward(attr_name: str): def decorator(func): # 从目标类的方法中复制元信息 original_func = getattr(Bar, func.__name__) @wraps(original_func) def wrapper(self, *args, **kwargs): return getattr(getattr(self, attr_name), func.__name__)(*args, **kwargs) return wrapper return decorator class Foo: def __init__(self, bar: Bar): self.bar = bar @forward("bar") def name(self): ...
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

