在我的代码中,我有一些复杂的Enum类型的类。例如:
class ComplexEnum(SomeOtherClass, Enum):
""" Some documentation """
MEMBER1 = SomeOtherClass(1)
MEMBER2 = SomeOtherClass(2)
def __init__(self, arg):
""" more doc """
pass
def somemethod(self):
""" more doc """
pass
@classmethod
def someclassmethod(cls, otherparam):
""" more doc """
pass
[当我现在使用autodoc使用Sphinx创建文档时,将跳过该类。我尝试将这样的自定义文档添加到我的conf.py文件中:
from sphinx.ext.autodoc import ClassDocumenter
class MyClassDocumenter(ClassDocumenter):
objtype = 'ComplexEnum'
directivetype = 'class'
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(member, ComplexEnum)
def setup(app):
app.add_autodocumenter(MyClassDocumenter)
但是这也不起作用。
如何使狮身人面像文档成为此类类?
这是Sphinx autodoc
中的错误,由于使用了Enum而发生。
可以通过精心编写.rst
文件的解决方法来解决。
话虽如此,我认为这是针对:
对应的.rst
:
my_module module
================
.. automodule:: my_module
:exclude-members: ComplexEnum
.. autoclass:: ComplexEnum
:members: some_method
:show-inheritance:
:exclude-members: MEMBER1, MEMBER2, __init__, some_classmethod
.. automethod:: some_classmethod
.. autoattribute:: MEMBER1
:annotation: = SomeOtherClass(1)
.. autoattribute:: MEMBER2
:annotation: = SomeOtherClass(2)
.. automethod:: __init__
.. autoclass:: SomeOtherClass
:special-members: __init__
我稍稍改动了代码以更好地解释解决方法的一些细节:
from enum import Enum
class SomeOtherClass:
""" SomeOtherClass documentation """
def __init__(self, other_arg):
"""Example of docstring on the __init__ method.
Args:
other_arg (int): Description of `other_arg`.
"""
self.other_arg = other_arg
class ComplexEnum(SomeOtherClass, Enum):
"""ComplexEnum documentation."""
#: :py:mod:`~my_package.my_module.SomeOtherClass`: MEMBER1 docstring comment.
MEMBER1 = SomeOtherClass(1)
#: :py:mod:`~my_package.my_module.SomeOtherClass`: MEMBER2 docstring comment.
MEMBER2 = SomeOtherClass(2)
def __init__(self, complex_arg):
"""Example of docstring on the __init__ method.
Args:
complex_arg (int): Description of `complex_arg`.
"""
self.complex_arg = complex_arg
super().__init__(complex_arg)
def some_method(self):
"""The doc of some_method."""
pass
@classmethod
def some_classmethod(cls, some_arg):
"""The doc of some_classmethod.
Args:
some_arg (int): Description of `some_arg`.
"""
pass
您的conf.py
可以保留为标准格式,我只添加了extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
以启用Google样式注释。
具体的引发错误的条件组合在@mzjn提供的链接中以及您的帖子中都已标识,即:
应该注意:使用带有@classmethod的简单枚举不会触发该错误。 (在这种情况下,.. autoclass::
的行为符合预期,几乎可以处理所有事情。)
该错误会影响多个autodoc
指令及其选项,从而导致它们具有意外行为。
编写.rst的必要解决方法如下:
请勿在枚举中使用:undoc-members:
,否则caos会爆发。如果这样做,则始终包含@classmethod而不选择描述符或文档字符串,而用:exclude-members:
排除它将无效。
下一个__init__
是最有问题的方面。有效的方法是用:exclude-members:
排除它,并明确地使用.. automethod:: __init__
。
与以上内容一起:您不能在__init__
中使用:automethod:
将@classmethod放在.rst
旁边,否则整个@classmethod将被“吸收”作为__init__
文档字符串的一部分。
对我来说,最有效的方法是使用:members:
和:exclude-members:
明确包含/排除Enum的所有部分。这样可以保证与autodoc
指令/选项的行为的最佳一致性。
[两个后记] >> 与记录枚举有关使用Sphinx(与bug没有直接关系)。
在记录Enum成员时,为了获得最佳一致性,请使用#:
语法而不是三引号'''
或内联#
。原因是因为后者经常被Sphinx“混淆”甚至丢失。
..member-order: by source
作为指令选项或在配置中,上述情况通常也是这样。最后,如果要让Enum成员的值显示在文档中,就像它们在类声明语法中一样。以我的经验,最好的方法是使用:annotation:
中所示的.rst
。否则,枚举成员将显示在这样的文档中:
将Python 3.8与Sphinx v2.2.2。一起使用