2009-07-09 9 views
9

Ich schreibe C-Extensions, und ich möchte die Signatur meiner Methoden für Introspektion sichtbar machen.Python C-Erweiterung: Methodensignaturen für die Dokumentation?

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

Wenn nun (nach dem Bau ...) ich das Modul laden und auf seine Hilfe suchen:

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

ich bekommen:

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. 

Ich möchte sein noch spezifischer und in der Lage zu ersetzen foo (...) von foo (Timeout, Flags = Keine)

Kann ich das tun? Wie?

Antwort

6

Meine übliche Vorgehensweise, um Dinge wie diese herauszufinden, ist: "Verwenden Sie die Quelle".

Grundsätzlich würde ich annehmen, dass die Standardmodule von Python eine solche Funktion verwenden würden, wenn sie verfügbar sind. Ein Blick auf die Quelle (for example here) sollte helfen, aber tatsächlich fügen sogar die Standardmodule den Prototyp nach der automatischen Ausgabe hinzu. Wie folgt:

So wie Upstream eine solche Funktion nicht verwendet, würde ich annehmen, dass es nicht da ist. :-)

Okay, ich habe gerade aktuelle python3k Quellen überprüft und dies ist immer noch der Fall. Diese Signatur wird in pydoc.py in den Pythonquellen hier generiert: pydoc.py. Relevante Auszug Start in Zeile 1260:

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

inspect.isfunction überprüft, ob das Objekt in der Dokumentation für eine Python-Funktion angefordert wird. Aber C implementierte Funktionen werden als Builtins betrachtet, daher erhalten Sie immer name(...) als Ausgabe.

3

Es war 7 Jahre , aber Sie können die Signatur für C-Erweiterung-Funktion und Klassen einschließen.

Python selbst verwendet die Argument Clinic, um dynamisch Signaturen zu generieren. Dann erstellen einige Mechaniker eine __text_signature__ und dies kann introspected sein (zum Beispiel mit help). @MartijnPieters erklärte diesen Prozess ziemlich gut in this answer.

Sie können das Argument Klinik von Python tatsächlich bekommen und es in einer dynamischen Art und Weise tun, aber ich ziehe die manuelle Art und Weise:

In Ihrem Fall:

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

ich die Signatur der docstring Hinzufügen Habe dies in meinem Paket stark genutzt: iteration_utilities/src. So zeigt, dass es funktioniert Ich benutze eine der C-Erweiterungsfunktionen durch dieses Paket ausgesetzt:

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

Das docstring für diese Funktion this file definiert ist.

Es ist wichtig zu erkennen, dass diese für Python nicht möglich ist < 3.4 und Sie müssen einige Regeln beachten:

  • Sie müssen --\n\n nach der Unterzeichnung Definitionszeile enthalten.

  • Die Signatur muss in der ersten Zeile des Docstrings stehen.

  • Die Signatur muss gültig sein, d. H. foo(a, b=1, c) schlägt fehl, da es nicht möglich ist, Positionsargumente nach Argumenten mit Standard zu definieren.

  • Sie können nur eine Signatur angeben. So ist es nicht funktioniert, wenn Sie so etwas wie verwenden:

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

funktioniert das mit 'inspect.signature'? – Eric

+0

@Eric Ja, solange es den oben genannten Regeln von "__text_signature__" entspricht. – MSeifert

+0

Klingt wie eine Sache, dass 'numpy' einen Patch für – Eric

Verwandte Themen