如何动态修改Python实例方法的文档字符串?
解决方法
你遇到的问题根源在于:Python中实例的**方法对象(method)**的__doc__是只读的,它直接引用类层面定义的原始函数的文档字符串,无法在实例上直接修改。以下是两种可行的实现方案:
方案一:将func实现为动态返回绑定方法的属性
通过property每次访问func时,动态生成带有当前f文档字符串的绑定方法:
import types class MyClass: def __init__(self, f): self._f = f @property def f(self): return self._f @f.setter def f(self, value): self._f = value @property def func(self): # 定义与原func逻辑一致的内部函数 def _func(): return self._f() # 同步目标函数的文档字符串和方法名称 _func.__doc__ = self._f.__doc__ _func.__name__ = "func" # 转换为绑定到当前实例的方法 return types.MethodType(_func, self)
测试示例
def func1(): """这是第一个函数的文档""" return True def func2(): """这是第二个函数的文档""" return False obj = MyClass(func1) print(obj.func()) # 输出:True help(obj.func) # 显示:这是第一个函数的文档 obj.f = func2 print(obj.func()) # 输出:False help(obj.func) # 显示:这是第二个函数的文档
方案二:使用__getattr__缓存动态方法
通过__getattr__拦截func的访问,生成一次后缓存到实例字典,避免重复创建,效率更高:
import types from functools import wraps class MyClass: def __init__(self, f): self._f = f @property def f(self): return self._f @f.setter def f(self, value): self._f = value # 清除缓存的func,确保下次访问时重新生成 self.__dict__.pop("func", None) def __getattr__(self, name): if name == "func": # 用wraps自动同步目标函数的文档等属性 @wraps(self._f) def _func(): return self._f() # 手动修正方法名称为原名称"func" _func.__name__ = "func" # 创建绑定方法并缓存到实例字典 bound_method = types.MethodType(_func, self) self.__dict__["func"] = bound_method return bound_method raise AttributeError(f"'MyClass' object has no attribute '{name}'")
这种方案在多次访问obj.func时不会重复创建方法对象,仅当f更新后才会重新生成带新文档的方法。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

