如何通过名称实现装饰器复制同模块/同类下函数的docstring
实现方案
我们可以利用inspect模块获取装饰器执行时的上层作用域栈帧,直接从对应作用域的局部变量中查找指定名称的源函数,天然适配模块级普通函数、类内部方法两种场景,实现代码如下:
import inspect from typing import Callable def copy_doc(source_name: str) -> Callable: def wrapper(func: Callable) -> Callable: # 取装饰器调用位置的上一层栈帧,即被装饰函数的定义作用域 caller_frame = inspect.stack()[1][0] source_func = caller_frame.f_locals.get(source_name) if source_func: func.__doc__ = source_func.__doc__ return func return wrapper
测试验证
场景1:同模块普通函数复制
def this() -> None: """Fun doc string""" return @copy_doc('this') def that() -> None: return print(that.__doc__) # 输出:Fun doc string
场景2:同一类内方法复制
class This: def foo(self) -> None: """Fun doc string""" return None @copy_doc('foo') def bar(self) -> None: return None print(This().bar.__doc__) # 输出:Fun doc string
注意事项
- 源函数/方法需要定义在被装饰函数的前面,装饰器执行时作用域内已存在对应的源函数才能正确获取docstring。
内容的提问来源于stack exchange,提问作者Trevor
相关产品推荐
相关产品推荐

