如何使用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
由于文档字符串是自由形式的,因此它实际上取决于您使用什么来解析代码以生成API文档。
我建议熟悉Sphinx标记,因为它被广泛使用,并且正在成为记录Python项目的事实上的标准,部分原因是出色的readthedocs.org服务。将Sphinx文档中的一个示例改写为Python代码片段:
def send_message(sender, recipient, message_body, priority=1) -> int:
"""
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代码。
注意,这里有一个类似的问题和类似的答案……
约定:
PEP 257文档字符串约定
PEP 287 reStructuredText文档字符串格式
工具:
Epydoc:为Python自动生成API文档
autodoc -包括文档字符串中的文档
PyCharm对文档字符串有一些很好的支持
更新:从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这样的工具可以很容易地利用它。
在类型提示回答(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/
由于文档字符串是自由形式的,因此它实际上取决于您使用什么来解析代码以生成API文档。
我建议熟悉Sphinx标记,因为它被广泛使用,并且正在成为记录Python项目的事实上的标准,部分原因是出色的readthedocs.org服务。将Sphinx文档中的一个示例改写为Python代码片段:
def send_message(sender, recipient, message_body, priority=1) -> int:
"""
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代码。
注意,这里有一个类似的问题和类似的答案……
主流的是,正如这里的其他答案已经指出的,可能会采用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已经在另一条评论中指出的那样)是:
最重要的是,参数和它们的文档总是在一起,这带来了以下好处:
少输入(不需要重复变量名)
更改/移除变量时更容易维护。在重命名一些参数后,永远不会有一些孤儿参数文档段。
并且更容易找到遗漏的注释。
现在,有些人可能会认为这种风格看起来很“丑”。但我想说“丑”是一个主观的词。更中性的说法是,这种风格不是主流,所以你可能看起来不太熟悉,因此不太舒服。同样,“舒适”也是一个主观词。但关键是,上面描述的所有好处都是客观的。如果你遵循标准的方法,你是无法实现这些目标的。
希望在未来的某一天,会有一个文档生成器工具,也可以消费这样的内联样式。这将推动应用的普及。
PS:这个答案来自于我自己的偏好,只要我觉得合适,我就会使用内联注释。我也使用相同的内联样式来记录字典。