2009-07-09 10 views
9

私はCエクステンションを書いています。私は自分のメソッドのシグネチャをイントロスペクションで見えるようにしたいと思います。Python 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"); 
} 

:私はなりたい

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. 

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

私が取得しますさらに特定して置き換えることができるfoo(...)foo(タイムアウト、フラグ=なし)

これを行うことはできますか?どうやって?

答えて

6

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

基本的に、私は、pythonの標準モジュールが利用可能なときにそのような機能を使用すると推測します。ソース(for example here)を見ると、実際には標準モジュールでも自動出力後にプロトタイプが追加されます。このように:

[email protected]:~$ 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.pyのpythonソースのpydoc.pyに生成されています。ライン1260で始まる関連の抜粋:

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

inspect.isfunctionチェックドキュメントは、要求されたオブジェクトは、Pythonの関数である場合。しかし、Cの実装された関数は組み込み関数とみなされるので、出力として常にname(...)が得られます。

3

これは7年ですがですが、C-拡張機能のクラスとクラスを含めることができます。

Python自体がArgument Clinicを使用して署名を動的に生成します。次に、いくつかのメカニックは__text_signature__を作成し、これはイントロスペクト(例えば、help)である可能性があります。 @MartijnPietersはこのプロセスを非常によく説明しましたthis answerです。

あなたが実際のpythonから引数クリニックを取得し、動的な方法でそれを行うが、私は、マニュアルの方法を好むことがあります。ドキュメンテーション文字列に署名を追加する:

あなたのケースでは:

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."); 

I私のパッケージでこれを大量に使用しました:iteration_utilities/src

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

この関数のドキュメント文字列がthis fileに定義されています。だから、私はこのパッケージによって公開されたC-拡張機能のいずれかを使用する機能することを実証します。

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

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

  • 署名は、ドキュメントストリングの最初の行になければなりません。

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

  • 署名は1つのみです。あなたのようなものを使用するのであれば、それは動作しません:

    foo(a) 
    foo(x, a, b) 
    -- 
    
    Narrative documentation 
    
+0

'inspect.signature'でこの仕事をしていますか? – Eric

+0

@Ericはい、上記の '__text_signature__'の規則に従っている限りです。 – MSeifert

+0

「numpy」がパッチを必要とするようなものです – Eric

関連する問題