如何在Python中记录模块常量?

sky*_*ler 47 python restructuredtext python-sphinx

我有一个模块,errors.py其中定义了几个全局常量(注意:我知道Python没有常量,但我已经使用UPPERCASE按惯例定义了它们).

"""Indicates some unknown error."""
API_ERROR = 1

"""Indicates that the request was bad in some way."""
BAD_REQUEST = 2

"""Indicates that the request is missing required parameters."""
MISSING_PARAMS = 3
Run Code Online (Sandbox Code Playgroud)

使用reStructuredText如何记录这些常量?正如你所看到的,我已经在他们上面列出了一个文档字符串,但我没有找到任何表明这样做的文档,我只是猜测它.

aba*_*ert 55

不幸的是,变量(和常量)没有文档字符串.毕竟,变量只是整数的名称,并且您不希望1像对函数或类对象那样将docstring附加到数字.

如果您查看stdlib中的几乎任何模块pickle,您会看到他们使用的唯一文档是注释.是的,这意味着help(pickle)只显示:

DATA
    APPEND = b'a'
    APPENDS = b'e'
    …
Run Code Online (Sandbox Code Playgroud)

......完全无视评论.如果您希望您的文档显示在内置帮助中,则必须将它们添加到模块的文档字符串中,这不是完全理想的.


但是Sphinx可以做的不仅仅是内置的帮助.您可以将其配置为提取常量的注释,或者用于autodata半自动执行注释.例如:

#: Indicates some unknown error.
API_ERROR = 1
Run Code Online (Sandbox Code Playgroud)

#:任何赋值语句之前的多行或语句#:右侧的单个注释与autodoc选取的对象上的文档字符串有效地相同.其中包括处理内联rST,以及为变量名自动生成rST头; 没有什么额外的事情要做才能做到这一点.


作为旁注,您可能需要考虑使用enum而不是像这样的单独常量.如果您没有使用Python 3.4(您可能还没有...),那么有一个backport.enum3.2+ 的包,或者flufl.enum(它不相同,但它是相似的,因为它是stdlib模块的主要灵感) 2.6+.

枚举实例(不是flufl.enum,但stdlib/backport版本)甚至可以有docstrings:

class MyErrors(enum.Enum):
    """Indicates some unknown error."""
    API_ERROR = 1

    """Indicates that the request was bad in some way."""
    BAD_REQUEST = 2

    """Indicates that the request is missing required parameters."""
    MISSING_PARAMS = 3
Run Code Online (Sandbox Code Playgroud)

虽然不幸的是它们没有出现help(MyErrors.MISSING_PARAMS),但它们是Sphinx autodoc可以提供的文档字符串.

  • “毕竟,变量只是一个整数的名字”——一个函数名是一个变量,它只是一个函数的名字,一个类名是一个变量,它只是一个类的名字......而且内部的函数和类只是一些大整数...... (6认同)
  • @Alexey我认为你错过了那句话的要点。函数名称_没有_有文档字符串——函数_值_有。而且您不会想给数字 1 一个文档字符串,说明“API_ERROR”。 (2认同)
  • 好吧,但是 OP 的问题是关于记录“常量”,其值可以是函数、类或任何东西。允许记录一种类型的值但禁止记录另一种类型的值有点人为限制,但这并非完全不合理。然而,Python 似乎没有一种方便的机制来记录任何值,包括函数和类,如果它们是使用 `VAL =` 语法定义的。考虑`MyClass = namedtuple("MyClass", ("foo", "bar"))`。 (2认同)

Lou*_*uis 19

如果你在变量放一个字符串,那么sphinx将把它作为变量的文档.我知道它有效,因为我在整个地方都这样做.像这样:

FOO = 1
"""
Constant signifying foo.

Blah blah blah...
"""  # pylint: disable=W0105
Run Code Online (Sandbox Code Playgroud)

pylint指令告诉pylint避免将文档标记为无效的语句.


Rob*_*ahl 19

这是一个较老的问题,但我注意到缺少相关的答案.

或者你可以通过.. py:data ::在模块的docstring中包含常量的描述.这样,文档也可以通过交互式帮助获得.狮身人面像将很好地渲染.

"""
Docstring for my module.

.. data:: API_ERROR

    Indicates some unknown error.

.. data:: BAD_REQUEST

    Indicates that the request was bad in some way.

.. data:: MISSING_PARAMS

    Indicates that the request is missing required parameters.
"""
Run Code Online (Sandbox Code Playgroud)


Mik*_*maa 18

您可以使用散列+冒号来记录属性(类或模块级别).

  #: Use this content as input for moo to do bar
  MY_CONSTANT = "foo"
Run Code Online (Sandbox Code Playgroud)

这将是一些文件生成器.

这里的一个例子,找不到更好的一个Sphinx文档模块属性


JDG*_*JDG 6

以下对我的 Sphinx 2.4.4 有用:

foo.py

API_ERROR = 1
"""int: Indicates some unknown error."""

Run Code Online (Sandbox Code Playgroud)

然后记录它:

.. automodule:: foo.py 
    :members:

Run Code Online (Sandbox Code Playgroud)