Python C扩展:文档的方法签名?

Nic*_*zet 12 python documentation python-c-api

我正在编写C扩展,我想让我的方法的签名可见为内省.

static PyObject* foo(PyObject *self, PyObject *args) {

    /* blabla [...] */

}

PyDoc_STRVAR(
    foo_doc,
    "Great example function\n"
    "Arguments: (timeout, flags=None)\n"
    "Doc blahblah doc doc doc.");

static PyMethodDef methods[] = {
    {"foo", foo, METH_VARARGS, foo_doc},
    {NULL},
};

PyMODINIT_FUNC init_myexample(void) {
    (void) Py_InitModule3("_myexample", methods, "a simple example module");
}
Run Code Online (Sandbox Code Playgroud)

现在,如果(在构建它之后......)我加载模块并查看它的帮助:

>>> import _myexample
>>> help(_myexample)
Run Code Online (Sandbox Code Playgroud)

我会得到:

Help on module _myexample:

NAME
    _myexample - a simple example module

FILE
    /path/to/module/_myexample.so

FUNCTIONS
    foo(...)
        Great example function
        Arguments: (timeout, flags=None)
        Doc blahblah doc doc doc.
Run Code Online (Sandbox Code Playgroud)

我想更加具体,并能够代替富(...)富(超时,旗帜=无)

我可以这样做吗?怎么样?

MSe*_*ert 8

它已经有7年了但您可以包含C扩展功能和类的签名.

Python本身使用Argument Clinic来动态生成签名.然后一些机制创建一个__text_signature__,这可以被内省(例如help).@MartijnPieters在这个答案中很好地解释了这个过程.

您实际上可以从python获取参数诊所并以动态方式进行,但我更喜欢手动方式:将签名添加到docstring:

在你的情况下:

PyDoc_STRVAR(
    foo_doc,
    "foo(timeout, flags=None, /)\n"
    "--\n"
    "\n"
    "Great example function\n"
    "Arguments: (timeout, flags=None)\n"
    "Doc blahblah doc doc doc.");
Run Code Online (Sandbox Code Playgroud)

我在包装中大量使用了这个:iteration_utilities/src.因此,为了证明它有效,我使用了这个包暴露的C-extension函数之一:

>>> from iteration_utilities import minmax
>>> help(minmax)
Help on built-in function minmax in module iteration_utilities._cfuncs:

minmax(iterable, /, key, default)
    Computes the minimum and maximum values in one-pass using only
    ``1.5*len(iterable)`` comparisons. Recipe based on the snippet
    of Raymond Hettinger ([0]_) but significantly modified.

    Parameters
    ----------
    iterable : iterable
        The `iterable` for which to calculate the minimum and maximum.
[...]
Run Code Online (Sandbox Code Playgroud)

此函数的docstring定义此文件.

重要的是要意识到python <3.4是不可能的,你需要遵循一些规则:

  • 您需要--\n\n在签名定义行之后包含.

  • 签名必须位于docstring的第一行.

  • 签名必须有效,即foo(a, b=1, c)失败,因为在默认参数之后无法定义位置参数.

  • 您只能提供一个签名.所以如果你使用类似的东西它不起作用:

    foo(a)
    foo(x, a, b)
    --
    
    Narrative documentation
    
    Run Code Online (Sandbox Code Playgroud)


Blu*_*orn 6

我通常的方法是找出这样的事情:"使用源".

基本上,我认为python的标准模块在可用时会使用这样的功能.查看源代码(例如此处)应该有所帮助,但实际上即使是标准模块也会在自动输出后添加原型.像这样:

torsten@pulsar:~$ python2.6
>>> import fcntl
>>> help(fcntl.flock)
flock(...)
    flock(fd, operation)

    Perform the lock operation op on file descriptor fd.  See the Unix [...]

因为上游没有使用这样的功能,我认为它不存在.:-)

好的,我刚检查了当前的python3k源代码,情况仍然如此.这个签名是在pydoc.pypython源代码中生成的:pydoc.py.从第1260行开始的相关摘录:

        if inspect.isfunction(object):
            args, varargs, varkw, defaults = inspect.getargspec(object)
            ...
        else:
            argspec = '(...)'

inspect.isfunction检查请求文档的对象是否为Python函数.但C实现的函数被认为是内置函数,因此您将始终获得name(...)输出.