15

私は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");
}

ここで、(ビルド後に...)モジュールをロードして、そのヘルプを確認すると、次のようになります。

>>> import _myexample
>>> help(_myexample)

私は取得します:

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.

もっと具体的にして、foo(...)foo(timeout、flags = None)に置き換えられるようにしたいと思います。

これはできますか?どのように?

4

2 に答える 2

16

7年になりますが、C拡張関数とクラスのシグネチャを含めることができます

Python自体は、引数クリニックを使用して動的に署名を生成します。次に、一部のメカニックがを作成し__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.");

私は自分のパッケージでこれを多用しました:iteration_utilities/src。したがって、それが機能することを示すために、このパッケージで公開されているC拡張関数の1つを使用します。

>>> 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.
[...]

この関数のdocstringは、このファイルで定義されています。

これはpython<3.4では不可能であり、いくつかのルールに従う必要があることを理解することが重要です。

  • --\n\n署名定義行の後に含める必要があります。

  • 署名は、docstringの最初の行にある必要があります。

  • 署名は有効である必要があります。つまりfoo(a, b=1, c)、デフォルトでは引数の後に位置引数を定義できないため、失敗します。

  • 提供できる署名は1つだけです。したがって、次のようなものを使用すると機能しません。

    foo(a)
    foo(x, a, b)
    --
    
    Narrative documentation
    
于 2016-12-20T15:09:08.713 に答える
6

このようなことを知るための私の通常のアプローチは、「ソースを使用する」です。

基本的に、Pythonの標準モジュールは、利用可能な場合にそのような機能を使用すると思います。ソース(たとえばここ)を見ると役立つはずですが、実際には、標準モジュールでさえ、自動出力の後にプロトタイプを追加します。このような:

torsten @ pulsar:〜$ python2.6
>>>インポートfcntl
>>>ヘルプ(fcntl.flock)
群れ(...)
    flock(fd、operation)

    ファイル記述子fdに対してロック操作opを実行します。Unixを参照してください[...]

したがって、アップストリームはそのような機能を使用していないので、そこにはないと思います。:-)

さて、私は現在のpython3kソースをチェックしましたが、これはまだ当てはまります。その署名はpydoc.py、次のPythonソースで生成されます:pydoc.py。1260行目から始まる関連する抜粋:

        inspect.isfunction(object)の場合:
            args、varargs、varkw、defaults = inspect.getargspec(object)
            ..。
        そうしないと:
            argspec ='(...)'

inspect.isfunctionは、ドキュメントが要求されているオブジェクトがPython関数であるかどうかを確認します。ただし、Cで実装された関数は組み込み関数と見なされるため、常にname(...)出力として取得されます。

于 2009-07-09T16:11:30.060 に答える