我该如何防止Sphinx将"object"列为基类?

14

我有这个类:

class Class:
    pass
生成的文档(如果有必要,我使用了autodoc扩展程序)如下:

package.Class

     基类: object

object继承并不是对读者有用的信息,因此我不想在我的文档中包含它。我希望看到的输出如下所示:

package.Class


有没有一种方法可以将object从基类列表中排除?

你是不是使用 automodule 指令来记录每个模块成员的文档? - hoefling
@hoefling 是的。我的 module.rst 包含了通常由 sphinx-apidoc 生成的 .. automodule:: module :members: :undoc-members: :show-inheritance: - Aran-Fey
4个回答

13

实际上,这深深地嵌入在自动文档autodoc源代码中,并且没有关闭它的方法:

bases = [b.__module__ in ('__builtin__', 'builtins') and
         u':class:`%s`' % b.__name__ or
         u':class:`%s.%s`' % (b.__module__, b.__name__)
         for b in self.object.__bases__]
self.add_line(u'   ' + _(u'Bases: %s') % ', '.join(bases), sourcename)

object没有被特殊处理,没有内置的方法可以将其从列表中排除。


我找到的最好(自动化)解决方案是在autodoc上进行猴子补丁。

将以下内容添加到conf.py可以实现所需的行为:

# ClassDocumenter.add_directive_header uses ClassDocumenter.add_line to
#   write the class documentation.
# We'll monkeypatch the add_line method and intercept lines that begin
#   with "Bases:".
# In order to minimize the risk of accidentally intercepting a wrong line,
#   we'll apply this patch inside of the add_directive_header method.

from sphinx.ext.autodoc import ClassDocumenter, _

add_line = ClassDocumenter.add_line
line_to_delete = _(u'Bases: %s') % u':class:`object`'

def add_line_no_object_base(self, text, *args, **kwargs):
    if text.strip() == line_to_delete:
        return

    add_line(self, text, *args, **kwargs)

add_directive_header = ClassDocumenter.add_directive_header

def add_directive_header_no_object_base(self, *args, **kwargs):
    self.add_line = add_line_no_object_base.__get__(self)

    result = add_directive_header(self, *args, **kwargs)

    del self.add_line

    return result

ClassDocumenter.add_directive_header = add_directive_header_no_object_base

对我来说,“add_directive_header_no_object_base”从未被调用(我在那里添加了一个打印语句,但输出中没有任何内容)。 - AlwaysLearning
@AlwaysLearning Sphinx在控制台上做了一些魔法(用于美化输出),所以你的打印输出会被覆盖。尝试添加更多的\n - Andrei Korshikov

3

关于2022年6月和Sphinx v5.0.1,Aran-Fey的回答有点过时;在我的情况下有效的解决方案是替换这行代码:

line_to_delete = _(u'Bases: %s') % u':class:`object`'

使用这个:

line_to_delete = _(u'Bases: %s') % u':py:class:`object`'

对我来说,add_directive_header_no_object_base 从未被调用过(我在那里添加了一个打印语句,但输出中没有任何内容)。 - AlwaysLearning
我觉得现在是时候移除u了。我的意思是,现在字符串默认是Unicode的。顺便说一下,我更喜欢将sphinx.ext.autodoc中的_改为localize,因为我觉得我不会记得_是本地化函数。 - Andrei Korshikov
嗯,你不必“记住”这个,据我所知,这是一种事实上的标准,因为我个人至少在Python、PHP和Android Java中遇到过这种命名约定(尽管对最后一个不是100%确定),而且这些都是在不同的公司里。 - undefined
顺便说一句,在这个上下文中,_ 的主要目的是使具有大量本地化字符串的代码紧凑且易读,而实现这一目标的一种方式是使用别名,越短越好。我不会说 localize() 很短。 - undefined

1
声明:这可能不是最佳或最优雅的解决方案,因为你拥有的越多普通类(只子类object),你将不得不手动预处理每个类。
如果您使用autoclass指令来记录类,则不要使用:show-inheritance:选项。如果您使用automodule生成所有模块成员的文档,关闭:show-inheritance:将无济于事,因为每个类的基类都不会被记录在文档中。因此,我建议按照以下步骤进行: 步骤1:像这样在模块外部记录类而不使用:show-inheritance:
my\.mod module
--------------

.. automodule:: my.mod
   :members:
   :undoc-members:
   :show-inheritance:

.. autoclass:: Class
   :members:
   :undoc-members:

步骤2: 在你的conf.py中通过autodoc-skip-member钩子过滤模块的automodule文档中的Class类:

def skip_some_classes(app, what, name, obj, skip, options):
    return skip or name in ('Class',)  # define some better condition here

def setup(app):
    app.connect('autodoc-skip-member', skip_some_classes)

这样,除了Class之外的所有模块成员都将使用:show-inheritance:选项进行处理,而Class则会被单独处理。

谢谢,这个可行。不过需要手动操作的工作有点多于我所期望的。我已经可以想象自己在重构类的继承树时忘记更新rst文件了。我真正想要的是一个完全自动化的解决方案。 - Aran-Fey
1
顺便说一下,你可以将skip_some_classes定义为return skip or (isinstance(obj, type) and obj.__base__ is object) - Aran-Fey
是的,我也不喜欢这个解决方案,因为这样可能会导致巨大的维护成本,特别是如果项目仍在开发中。 - hoefling
问题在于,我没有看到仅使用autodoc钩子自动化的简单方法。当然,您可以monkeypatch sphinx.apidoc模块并覆盖例如create_module_file函数,对纯类进行分离以使其不被自动模块化,但这可能会更麻烦,而且可能不值得。 - hoefling

0

对我来说,这是一个非常简单的解决方案。

from sphinx.ext import autodoc

class MockedClassDocumenter(autodoc.ClassDocumenter):
    def add_line(self, line: str, source: str, *lineno: int) -> None:
        if line == "   Bases: :py:class:`object`":
            return
        super().add_line(line, source, *lineno)

autodoc.ClassDocumenter = MockedClassDocumenter

conf.py 文件中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接