You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Sphinx生成文档时如何让子类继承父类的Docstring?

问题:Sphinx中Dataclass子类无法继承父类Attributes文档

问题场景

使用Sphinx生成文档时,Dataclass子类B无法继承父类A的Attributes部分文档,已配置autodoc_inherit_docstrings=True,且无法使用装饰器方案。

最小复现代码

父类与子类代码:

@dataclass
class A():
    """
    Attributes:
        a:
            This is the variable 'a'
    """
    a: int = 0

@dataclass
class B(A):
    """
    Attributes:
        b:
            This is the variable 'b'
    """
    b: int = 0

Sphinx配置conf.py:

import os
import sys
sys.path.insert(0, os.path.abspath('../test_config'))
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.autodoc.typehints']
autodoc_inherit_docstrings = True

RST文件内容:

Classes
===================
.. autoclass:: test_config.A()

.. autoclass:: test_config.B()
   :members:
   :show-inheritance:
   :inherited-members:

原因分析

autodoc_inherit_docstrings=True仅控制类/方法级别的整体docstring继承,而sphinx.ext.napoleon在处理结构化的Attributes区块时,若子类自身定义了该区块,不会自动合并父类的属性文档。

解决方案

方案一:自定义Sphinx钩子合并属性文档(无业务代码侵入)

在conf.py中添加自定义处理函数,自动将父类的Attributes内容合并到子类的docstring中:

import os
import sys
sys.path.insert(0, os.path.abspath('../test_config'))
from sphinx.ext.napoleon.docstring import GoogleDocstring

extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.autodoc.typehints']
autodoc_inherit_docstrings = True

def merge_parent_attributes(app, what, name, obj, options, lines):
    if what != 'class' or not hasattr(obj, '__bases__'):
        return
    # 遍历父类(跳过object)
    for base in obj.__bases__:
        if base is object:
            continue
        base_doc = base.__doc__
        if not base_doc:
            continue
        # 解析父类docstring提取Attributes部分
        base_google_doc = GoogleDocstring(base_doc)
        base_attr_lines = []
        in_attr_block = False
        for line in base_google_doc.lines:
            stripped_line = line.strip()
            if stripped_line == 'Attributes:':
                in_attr_block = True
                base_attr_lines.append(line)
            elif in_attr_block:
                # 遇到非缩进的新区块则停止
                if stripped_line and not line.startswith('    '):
                    break
                base_attr_lines.append(line)
        if not base_attr_lines:
            continue
        # 找到子类docstring中的Attributes插入位置
        insert_pos = len(lines)
        in_sub_attr_block = False
        for idx, line in enumerate(lines):
            if line.strip() == 'Attributes:':
                in_sub_attr_block = True
                insert_pos = idx + 1
                break
        # 子类无Attributes区块则新增
        if not in_sub_attr_block:
            lines.extend(['', 'Attributes:'])
            insert_pos = len(lines)
        # 插入父类属性(跳过父类的Attributes标题行)
        lines[insert_pos:insert_pos] = base_attr_lines[1:]

def setup(app):
    app.connect('autodoc-process-docstring', merge_parent_attributes)

方案二:调整子类Docstring写法

去掉子类的Attributes:标题,直接在类docstring中写属性说明,Napoleon会自动合并父类Attributes并识别子类属性:

@dataclass
class B(A):
    """
    类B的描述(可选)

    b:
        This is the variable 'b'
    """
    b: int = 0

补充说明

Sphinx原生确实不支持结构化docstring区块(如Attributes)的自动合并,需通过自定义钩子或调整docstring写法实现。

内容的提问来源于stack exchange,提问作者Gokul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:55:25