首页 > 解决方案 > 自动摘要生成的文档缺少除 __init__ 之外的所有 dunder 方法

问题描述

我正在使用 Sphinx 的自动摘要为我的模块的每个成员自动生成单独的 rst 文件。文档按预期创建,除了生成的 rst 文件缺少除__init__.

在我的conf.py我有以下几行:

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.autosummary',
]

autosummary_generate = True
autosummary_imported_members = True

考虑下面的虚拟类,它包含 dunder 和常规公共方法:

class MyClassA:

    def __init__(self):
        r'__init__ docstring'
        pass

    def __call__(self):
        r'__call__ docstring'
        pass

    def __len__(self):
        r'__len__ docstring'
        pass

    def public_method_1(self):
        r'public_method_1 docstring'
        pass

    def public_method_2(self):
        r'public_method_2 docstring'
        pass

在我的主 rst 文件中,我设置了自动摘要,如下所示:

.. autosummary::
    :toctree: my_module_members

    my_module.MyClassA
    my_module.MyClassB

正如预期的那样,autosummary/my_module_members为模块的每个成员创建了一个以单独的 rst 文件命名的子目录。但仅__init__在这些自动生成的 rst 文件的方法部分中列出。例如:

my_module.MyClassA
==================

.. currentmodule:: my_module

.. autoclass:: MyClassA




   .. rubric:: Methods

   .. autosummary::

      ~MyClassA.__init__
      ~MyClassA.public_method_1
      ~MyClassA.public_method_2

因此,在生成的 html 文档中,只有这三个方法列在方法表中,并且__call____len__存在:

在此处输入图像描述

所以我的问题是以这种方式使用自动摘要时如何包含所有特殊方法?

标签: pythonpython-sphinxmagic-methods

解决方案


问题在于自动摘要用于类的默认模板。这是文档中的相关页面,但直接查看默认模板更有帮助:

# In the sphinx v3.0.4 source code:
# sphinx/ext/autosummary/templates/autosummary/class.rst
{{ fullname | escape | underline}}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}

   {% block methods %}
   .. automethod:: __init__

   {% if methods %}
   .. rubric:: Methods

   .. autosummary::
   {% for item in methods %}
      ~{{ name }}.{{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

   {% block attributes %}
   {% if attributes %}
   .. rubric:: Attributes

   .. autosummary::
   {% for item in attributes %}
      ~{{ name }}.{{ item }}
   {%- endfor %}
   {% endif %}
   {% endblock %}

您可以看到此模板如何对应于为您的项目生成的存根文件(尽管我不确定您的为什么缺少该.. automethod:: __init__行;也许我们有不同版本的 sphinx)。重要的部分是{% for item in methods %}循环。上面链接的文档简要提到methods只包括“公共”方法,这意味着方法不以下划线开头。 __init__()也被认为是公开的,根据第 242 行sphinx/ext/autosummary/generate.py,尽管这似乎没有在任何地方记录。所以希望这能解释你所看到的行为。

考虑到这一点,我可以想到三种方法来在文档中包含所有特殊方法:

  1. 提供一个使用members而不是methods. 这应该记录所有内容,但会消除方法、属性、继承成员、内部类等之间的区别。

  2. 这没有记录,我也没有尝试过,看起来你可以替换methodsall_methods在自动摘要中包含所有方法(再次参见第 242 行)。但是,公共方法和私有方法之间没有任何区别。

  3. 尝试使用autoclasstoc。完全披露:这是我编写的一个包,目的是更好地总结 sphinx 文档中的类方法。它比自动摘要更具可配置性,并且默认包含所有方法。它还折叠继承的方法,这对于大类来说可能非常好,尽管这可能与您相关,也可能不相关。

    这个页面描述了如何结合使用 autoclasstoc 和 autosummary,但它的要点是你需要一个看起来像这样的自定义模板:

    {{ fullname | escape | underline}}
    
    .. currentmodule:: {{ module }}
    
    .. autoclass:: {{ objname }}
       :members:
       :special-members:
    
        .. autoclasstoc::
    

推荐阅读