不能只靠 __doc__ 字段手动拼文档,因为它是静态字符串,无结构、不处理继承或类型注解,无法自动提取参数和返回值,且需工具链(如 sphinx + autodoc)解析和组织。

直接用 __doc__ 生成可用的 API 文档不现实——它只是字符串,没有结构、没有跨文件索引、不处理继承或类型注解,更不会自动提取参数和返回值。真要靠它出文档,得搭配工具链,而不是裸写 docstring 就完事。
为什么不能只靠 __doc__ 字段手动拼文档
__doc__ 是每个类、函数、模块自带的字符串属性,但它是静态的、孤立的:类里的方法 __doc__ 不会自动关联到类名下,父类 docstring 不会自动合并进子类,def func(x: int) -> str: 这种类型信息也不会被 __doc__ 自动识别。你手写一段 docstring,Python 只存它,不解析它。
- 手动读取所有
__doc__再组织成 HTML 或 Markdown,代码量大、易漏、难维护 - 无法识别
:param x:或:return:这类 reStructuredText 标记,除非你自己写解析器 - 遇到
@property、@classmethod、动态生成的方法(如用getattr或__getattr__),__doc__可能为空或不可达
用 sphinx + sphinx-autodoc 把 __doc__ 转成真实文档
这是目前最稳妥的路径:Sphinx 读取源码,提取对象结构,再把 __doc__ 渲染进对应位置。关键不是“用 __doc__”,而是“让 Sphinx 知道该读哪个 __doc__”。
- 必须在
conf.py中启用extensions = ['sphinx.ext.autodoc'] - 在 .rst 文件里写
.. autoclass:: mypackage.MyClass,Sphinx 才会触发对MyClass.__doc__的提取 - 加
:members:和:undoc-members:控制是否列出无 docstring 的成员(避免漏掉重要方法) - 默认只读 public 成员(不以下划线开头),要包含私有方法得加
:private-members:
docstring 格式选 google 还是 numpy?影响生成效果
Sphinx 本身不强制格式,但 sphinx-autodoc 配合 sphinx.ext.napoleon 插件才能正确解析参数、返回值、异常等结构。选哪种,取决于团队习惯和已有注释风格。
-
google风格用空行分隔描述与参数块,写起来快:"""Get user by ID. <p>Args: user_id (int): unique identifier Returns: dict: user data """</p>
-
numpy风格字段对齐严格,适合复杂签名:"""Get user by ID. <h2>Parameters</h2><p>user_id : int unique identifier</p><h2>Returns</h2><p>dict user data """</p>
- 无论哪种,都得在
conf.py里配napoleon_google_docstring = True或napoleon_numpy_docstring = True
常见坑:继承、重载、动态属性让 __doc__ 失效
父类方法没写 docstring,子类重写了但没补 docstring,sphinx-autodoc 默认不继承父类文档;__getattr__ 返回的属性根本不在 AST 里,autoclass 压根看不到它。
- 显式用
:inherited-members:拉入父类文档,但注意这会把整个父类方法都列出来,未必符合预期 - 对动态属性,只能手动在 .rst 里补
.. py:attribute:: obj.dynamic_prop并写 docstring -
@cached_property或functools.cached_property的 docstring 必须写在装饰器外层,否则autodoc读不到 - 如果用了
__slots__且没定义__doc__,某些旧版 Sphinx 会跳过该类——确保每个关键类都有显式 docstring
真正花时间的不是写 docstring,而是让工具链准确识别哪些对象该出现在文档里、以什么粒度、带哪些元信息。把 __doc__ 当作数据源没问题,但它从来不是文档生成的起点,只是中间一环。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











