如何用参数记录方法?


139

如何使用Python的文档字符串来记录带有参数的方法?

编辑: PEP 257给出了这个例子:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

这是大多数Python开发人员使用的约定吗?

Keyword arguments:
<parameter name> -- Definition (default value if any)

我期待一些更正式的东西,例如

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    @param: real The real part (default 0.0)
    @param: imag The imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

环境:Python 2.7.1


1
您阅读过PEP 257吗?python.org/dev/peps/pep-0257
NPE

1
这里有几种“标准”,但采用一种实用的方法,尤其是如果您喜欢正式的东西,我建议您使用狮身人面像。它与Pycharm的集成使生成结构良好的文档字符串相当轻松。恕我直言
jojo

Answers:


86

根据我的经验,numpy的文档字符串公约(PEP257超集)是最广泛的传播遵循惯例,它们也通过工具,如支持的狮身人面像

一个例子:

Parameters
----------
x : type
    Description of parameter `x`.

2
这更接近我的预期。不幸的是,我选择了普通的PEP 257并添加了自己的约定(以丢失自动生成的HTML / PDF文档为代价)。但是,下次,我将选择此解决方案。谢谢。
David Andreoletti

5
当我尝试处理您建议的文档字符串时,Sphinx抱怨SEVERE: Unexpected section title–您是否知道使Sphinx更快乐的方法?
布兰登·罗兹

@BrandonRhodes此链接讨论了如何在Sphinx中使用这些约定:github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Vladimir Keleshev 2015年

3
其实之前没有一个空间Description。我检查了numpy文档,因为我立即注意到并想到“请稍等,为什么它是三个空格?这很奇怪。谁会使用三个空格?”
Zelphir Kaltstahl '16

6
在提出问题时,这可能是最好的答案,但我认为截至目前(2017年末),狮身人面像已经取得了胜利。
亚历克斯L

120

由于文档字符串是自由格式的,所以它实际上取决于您用来解析代码以生成API文档的内容。

我建议您熟悉Sphinx标记,因为它已被广泛使用并且已成为记录Python项目的实际标准,部分原因在于出色的readthedocs.org服务。要将Sphinx文档中的示例解释为Python代码段,请执行以下操作:

def send_message(sender, recipient, message_body, priority=1):
   '''
   Send a message to a recipient

   :param str sender: The person sending the message
   :param str recipient: The recipient of the message
   :param str message_body: The body of the message
   :param priority: The priority of the message, can be a number 1-5
   :type priority: integer or None
   :return: the message id
   :rtype: int
   :raises ValueError: if the message_body exceeds 160 characters
   :raises TypeError: if the message_body is not a basestring
   '''

该标记支持文档之间以及其他之间的交叉引用。请注意,Sphinx文档使用(例如),:py:attr:而您只能:attr:在从源代码进行文档记录时使用。

自然,还有其他工具可以记录API。有更经典的Doxygen使用\param 命令,但是这些命令并非像Sphinx一样专门用于记录Python代码。

请注意,这里有一个类似的问题答案相似


9
这是默认情况下PyCharm的评论自动生成所使用的样式
Josiah Yoder

诸如物料清单之类的复合类型的语法怎么样?
matanster

那么它是一个list
anarcat

33

约定:

工具:


更新:从Python 3.5开始,您可以使用类型提示,这是一种紧凑的,机器可读的语法:

from typing import Dict, Union

def foo(i: int, d: Dict[str, Union[str, int]]) -> int:
    """
    Explanation: this function takes two arguments: `i` and `d`.
    `i` is annotated simply as `int`. `d` is a dictionary with `str` keys
    and values that can be either `str` or `int`.

    The return type is `int`.

    """

这种语法的主要优点是它是由语言定义的,而且语言明确,因此PyCharm之类的工具可以轻松地从中受益。


12
尽管现在最能回答这个问题,但是以上两个PEP都没有提供约定来指定方法的参数类型。
koriander

11

python doc字符串是自由格式的,您可以按自己喜欢的任何方式对其进行记录。

例子:

def mymethod(self, foo, bars):
    """
    Does neat stuff!
    Parameters:
      foo - a foo of type FooType to bar with.
      bars - The list of bars
    """

现在,有一些约定,但是python没有强制执行任何约定。有些项目有自己的约定。一些使用文档字符串的工具也遵循特定的约定。



3

正如此处其他答案所指出的那样,主流可能是Sphinx方法,以便您以后可以使用Sphinx生成那些精美的文档。

话虽如此,我个人有时还是采用内联评论风格。

def complex(  # Form a complex number
        real=0.0,  # the real part (default 0.0)
        imag=0.0  # the imaginary part (default 0.0)
        ):  # Returns a complex number.
    """Form a complex number.

    I may still use the mainstream docstring notation,
    if I foresee a need to use some other tools
    to generate an HTML online doc later
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    other_code()

这里还有一个示例,内联记录了一些小细节:

def foo(  # Note that how I use the parenthesis rather than backslash "\"
          # to natually break the function definition into multiple lines.
        a_very_long_parameter_name,
            # The "inline" text does not really have to be at same line,
            # when your parameter name is very long.
            # Besides, you can use this way to have multiple lines doc too.
            # The one extra level indentation here natually matches the
            # original Python indentation style.
            #
            # This parameter represents blah blah
            # blah blah
            # blah blah
        param_b,  # Some description about parameter B.
            # Some more description about parameter B.
            # As you probably noticed, the vertical alignment of pound sign
            # is less a concern IMHO, as long as your docs are intuitively
            # readable.
        last_param,  # As a side note, you can use an optional comma for
                     # your last parameter, as you can do in multi-line list
                     # or dict declaration.
        ):  # So this ending parenthesis occupying its own line provides a
            # perfect chance to use inline doc to document the return value,
            # despite of its unhappy face appearance. :)
    pass

好处(如@ mark-horvath在另一条评论中已经指出的)是:

  • 最重要的是,参数及其文档始终保持在一起,这带来了以下好处:
  • 更少的输入(无需重复变量名)
  • 更改/删除变量时更容易维护。重命名某些参数后,将永远不会有任何孤立参数doc段落。
  • 更容易找到遗漏的评论。

现在,有些人可能认为这种样式看起来“丑陋”。但是我会说“丑陋”是一个主观的词。更为中性的说法是,这种风格不是主流,因此您看起来不太熟悉,因此不太舒适。同样,“舒适”也是一个主观词。但是关键是,上述所有好处都是客观的。如果遵循标准方法,则无法实现它们。

希望在将来的某一天,将有一个文档生成器工具也可以使用这种内联样式。这将推动采用。

PS:这个答案来自我自己的偏爱,即在我认为合适时使用内联注释。我也使用相同的内联样式来记录字典


1

建立在类型提示答案(https://stackoverflow.com/a/9195565/2418922)的基础上,该答案提供了一种更好的结构化方式来记录参数类型,还存在一种结构化方式来记录参数的类型和描述:

def copy_net(
    infile: (str, 'The name of the file to send'),
    host: (str, 'The host to send the file to'),
    port: (int, 'The port to connect to')):

    pass

示例取自:https : //pypi.org/project/autocommand/


1
这是官方语法吗?它超级有用,但是我在官方文档/
PEPs中

1
如果有PEP,我也想知道。
DreamFlasher

-1

文档字符串仅在交互式环境(例如Python shell)中有用。在记录将不会交互使用的对象(例如内部对象,框架回调)时,您最好使用常规注释。这是我用来将缩进的注释挂在项目上的样式,每个项目都在自己的行上,因此您知道该注释适用于:

def Recomputate \
  (
    TheRotaryGyrator,
      # the rotary gyrator to operate on
    Computrons,
      # the computrons to perform the recomputation with
    Forthwith,
      # whether to recomputate forthwith or at one's leisure
  ) :
  # recomputates the specified rotary gyrator with
  # the desired computrons.
  ...
#end Recomputate

您无法使用docstrings做这种事情。


46
哦,这看起来很丑。
Misha Akovantsev

1
丑陋的是吗?有趣的主意...也是。
大卫,

2
变量的内联注释非常明智,键入更少(无需重复变量名称),更改/删除变量时更易于维护...更容易找到缺少的注释。将其与签名下方的适当文档字符串结合使用。+1
马克·霍瓦斯

那不能作为文档。如果您这样评论您的软件包,而PyCharm用户下载了该软件包,则他们将无法在不访问文档的情况下检查每个参数的作用-您将无法使用任何软件生成该文档。除非你自己做。这就是OP要求在文档字符串中指定它的原因。抱歉,这么晚了。

这太可怕了。
Michael Walters '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.