记录 * * kwargs 参数的正确方法是什么?

我使用 狮身人面像Autodoc 分机为我的 Python 模块生成 API 文档。虽然我可以看到如何很好地记录特定的参数,但是我找不到如何记录 **kwargs参数的示例。

有没有人有一个很好的例子来清楚地记录这些?

63465 次浏览

我认为 subprocess模块的文件是一个很好的例子。给出 顶级/家长级的所有参数的详尽列表。然后只需参考该列表的所有其他事件的 **kwargs

如果其他人正在寻找一些有效的语法。.下面是一个 docstring 示例。我就是这样做的,我希望它对你们有用,但我不能声称它符合任何特定的东西。

def bar(x=True, y=False):
"""
Just some silly bar function.


:Parameters:
- `x` (`bool`) - dummy description for x
- `y` (`string`) - dummy description for y
:return: (`string`) concatenation of x and y.
"""
return str(x) + y


def foo (a, b, **kwargs):
"""
Do foo on a, b and some other objects.


:Parameters:
- `a` (`int`) - A number.
- `b` (`int`, `string`) - Another number, or maybe a string.
- `\**kwargs` - remaining keyword arguments are passed to `bar`


:return: Success
:rtype: `bool`
"""
return len(str(a) + str(b) + bar(**kwargs)) > 20

在他们的文档中有一个 Sphinx 的 Doctstring 示例:

def public_fn_with_googley_docstring(name, state=None):
"""This function does something.


Args:
name (str):  The name to use.


Kwargs:
state (bool): Current state to be in.


Returns:
int.  The return code::


0 -- Success!
1 -- No good.
2 -- Try again.


Raises:
AttributeError, KeyError


A really great idea.  A way you might use me is


>>> print public_fn_with_googley_docstring(name='foo', state=None)
0


BTW, this always returns 0.  **NEVER** use with :class:`MyPublicClass`.


"""
return 0

尽管你明确地问到了 ,我还是要指出 Google Python 风格指南。他们的 docstring 示例似乎暗示他们不会特别指出 kwargs。(other _ 弱智变量 = 无)

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
"""Fetches rows from a Bigtable.


Retrieves rows pertaining to the given keys from the Table instance
represented by big_table.  Silly things may happen if
other_silly_variable is not None.


Args:
big_table: An open Bigtable Table instance.
keys: A sequence of strings representing the key of each table row
to fetch.
other_silly_variable: Another optional variable, that has a much
longer name than the other args, and which does nothing.


Returns:
A dict mapping keys to the corresponding table row data
fetched. Each row is represented as a tuple of strings. For
example:


{'Serak': ('Rigel VII', 'Preparer'),
'Zim': ('Irk', 'Invader'),
'Lrrr': ('Omicron Persei 8', 'Emperor')}


If a key from the keys argument is missing from the dictionary,
then that row was not found in the table.


Raises:
IOError: An error occurred accessing the bigtable.Table object.
"""
pass

A-B-B 对引用子流程管理文档的公认答案有疑问。如果您导入一个模块,您可以通过 spect.getsource 快速查看模块 docstring。

使用 Silent Ghost 推荐的 python 解释器的一个示例:

>>> import subprocess
>>> import inspect
>>> import print inspect.getsource(subprocess)

当然,您也可以通过 help 函数查看模块文档

我个人并不喜欢以 kwargs 为例子的子进程 docstring,但是与 Google 示例一样,它并不像 Sphinx 文档示例中所示的那样单独列出 kwargs。

def call(*popenargs, **kwargs):
"""Run command with arguments.  Wait for command to complete, then
return the returncode attribute.


The arguments are the same as for the Popen constructor.  Example:


retcode = call(["ls", "-l"])
"""
return Popen(*popenargs, **kwargs).wait()

我包含了 A-B-B 问题的答案,因为值得注意的是,您可以通过这种方式查看任何模块的源代码或文档,以获得注释代码的见解和灵感。

在找到这个问题之后,我选择了下面这个问题,它是有效的 Sphinx,并且运行得相当好:

def some_function(first, second="two", **kwargs):
r"""Fetches and returns this thing


:param first:
The first parameter
:type first: ``int``
:param second:
The second parameter
:type second: ``str``
:param \**kwargs:
See below


:Keyword Arguments:
* *extra* (``list``) --
Extra stuff
* *supplement* (``dict``) --
Additional content


"""

需要使用 r"""..."""使其成为一个“原始的”文档字符串,从而保持 \*的完整性(Sphinx 可以选择字面的 *,而不是“强调”的开头)。

所选择的格式(带括号类型和以 m 破折号分隔的描述的项目符号列表)只是为了匹配 Sphinx 提供的自动格式。

一旦你努力使“ Keyword Arguments”部分看起来像默认的“ Parameter”部分,似乎从一开始滚动你自己的参数部分会更容易(根据其他一些答案) ,但作为概念的证明,如果你已经在使用 Sphinx,这是一种实现补充 **kwargs的漂亮外观的方法。

Sphinx 解析的 GoogleStyle 文档字符串

免责声明: 未经测试。

Sphinx docstring 示例的这个切口,*args**kwargs留下了 未扩张的:

def module_level_function(param1, *args, param2=None, **kwargs):
"""
...


Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.

我将 建议紧凑性的解决方案如下:

    """
Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
*param3 (int): description
*param4 (str):
...
**key1 (int): description
**key2 (int): description
...

注意,**key参数不需要 Optional

否则 ,您可以尝试在 Other Parameters下显式列出 * args,在 Keyword Args下显式列出 **kwargs(参见 Docstring 节) :

    """
Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
    

Other Parameters:
param3 (int): description
param4 (str):
...


Keyword Args:
key1 (int): description
key2 (int): description
...

这取决于您使用的文档样式,但是如果您使用的是 Numpydoc样式,建议使用 Other Parameters来记录 **kwargs

例如,下面是 Quorian 的例子:

def some_function(first, second="two", **kwargs):
"""Fetches and returns this thing


Parameters
----------
first : `int`
The first parameter
second : `str`, optional
The second parameter


Other Parameters
----------------
extra : `list`, optional
Extra stuff. Default ``[]``.
suplement : `dict`, optional
Additional content. Default ``{'key' : 42}``.
"""

特别要注意的是,建议给出 kwargs 的默认值,因为从函数签名来看,这些默认值并不明显。

如果您正在寻找如何在 Numpydoc风格中做到这一点,您可以简单地使用 在“参数”部分中提及 **kwargs,但不指定类型-如来自 sphinx 扩展那不勒斯的 Numpydoc 的例子和来自大熊猫文档 sprint 2018的 文档字符串指南所示。

下面是我从 LSST 开发指南中发现的一个例子,它很好地解释了 **kwargs参数的 描述应该是什么:

def demoFunction(namedArg, *args, flag=False, **kwargs):
"""Demonstrate documentation for additional keyword and
positional arguments.


Parameters
----------
namedArg : `str`
A named argument that is documented like always.
*args : `str`
Additional names.


Notice how the type is singular since the user is expected to pass individual
`str` arguments, even though the function itself sees ``args`` as an iterable
of `str` objects).
flag : `bool`
A regular keyword argument.
**kwargs
Additional keyword arguments passed to `otherApi`.


Usually kwargs are used to pass parameters to other functions and
methods. If that is the case, be sure to mention (and link) the
API or APIs that receive the keyword arguments.


If kwargs are being used to generate a `dict`, use the description to
document the use of the keys and the types of the values.
"""

或者,在@Jonas Adler 建议的基础上,我发现 将 ABC0及其描述放在 Other Parameters部分更好——甚至 matplotlib 文档指南中的 这个例子也是这样建议的。

我无法找到到文档的实际链接,但是这个工作(使用 Sphinx3.4.3) :

class Foo:
"""A Foo implementation


:param str foo: Foo
:param int bar: Bar
:keyword str key1: kwarg 1
:keyword str key2: kwarg 2
:keyword int key3: kwarg 3
"""


def __init__(self, foo, bar, **kwargs):
pass