Python C-Erweiterung: Methodensignaturen für die Dokumentation?
-
12-09-2019 - |
Frage
I C-Erweiterungen schreibe, und ich möchte die Unterschrift meiner Methoden sichtbar für Selbstbeobachtung machen.
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 es ...) ich das Modul laden und auf seiner Hilfe aussehen:
>>> 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 noch spezifischere und in der Lage sein, ersetzen foo (...) von foo (Timeout, flags = None)
Kann ich das tun? Wie?
Lösung
Mein üblicher Ansatz, sich über Dinge wie dies ist: „die Quelle verwenden“
.Im Grunde würde ich davon ausgehen, dass die Standard-Module von Python ein solches Feature, wenn verfügbar verwenden würde. Mit Blick auf die Quelle ( zum Beispiel hier soll) helfen, aber in der Tat auch die Standard-Module den Prototyp nach der automatischen Ausgabe hinzufügen. Wie folgt aus:
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 [...]
So wie stromaufwärts ist ein solches Feature nicht verwenden, würde ich nehme an, es ist nicht da. : -)
Okay, ich habe gerade überprüft aktuelle python3k Quellen und das ist immer noch der Fall ist. Das Signatur wird in pydoc.py
in den Python Quellen erzeugt hier: 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 implementierten Funktionen builtins betrachtet werden, deshalb werden Sie immer als Ausgabe erhalten name(...)
.
Andere Tipps
Es wurde 7 Jahre Sie können jedoch die Signatur für C-Erweiterungsfunktion und Klassen umfassen .
Python selbst verwendet das Argument Clinic Unterschriften dynamisch zu generieren. Dann erstellen Sie einige Mechanik einen __text_signature__
und dies kann (zum Beispiel mit help
) introspected werden. @MartijnPieters erklärt diesen Prozess ganz gut in diese Antwort .
Sie können tatsächlich das Argument Klinik von Python bekommen und tun es in einer dynamischen Art und Weise, aber ich bevorzuge die manuelle Art und Weise: die Unterschrift zum docstring Hinzufügen:
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 habe die starke Nutzung von in meinem Paket: iteration_utilities/src
. So zeigen, 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 definiert diese Datei .
Es ist wichtig zu erkennen, dass dies 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 in der ersten Zeile des docstring sein muss.
-
Die Signatur muss gültig sein, das heißt
foo(a, b=1, c)
schlägt fehl, weil es nicht möglich ist, Positionsargument nach Argumenten mit Standard zu definieren. -
können Sie stellen nur eine Unterschrift. So ist es nicht funktioniert, wenn Sie etwas verwenden wie:
foo(a) foo(x, a, b) -- Narrative documentation