Domanda

Le scrivo estensioni C, e mi piacerebbe fare la firma dei miei metodi visibile per l'introspezione.

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

Ora, se (dopo costruirlo ...) che carico il modulo e guardo il suo aiuto:

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

mi metterò:

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.

Mi piacerebbe essere ancora più specifici ed essere in grado di sostituire foo (...) di foo (timeout, flags = None)

Come posso fare? Come?

È stato utile?

Soluzione

Il mio approccio al solito per scoprire su cose come questo è: "utilizzare la fonte"

.

Fondamentalmente, voglio presumere che i moduli standard di pitone userebbero tale caratteristica quando disponibile. Guardando alla fonte ( per esempio qui ) dovrebbe aiutare, ma in realtà anche i moduli standard aggiungere il prototipo dopo l'uscita automatica. In questo modo:

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

Quindi, come a monte non sta usando una tale funzione, io suppongo che non c'è. : -)

Va bene, ho appena controllato le fonti python3k attuali e questo è ancora il caso. Che la firma è generato in pydoc.py nelle fonti pitone qui: pydoc.py . Rilevante stralcio di partenza in linea 1260:

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

inspect.isfunction verifica se l'oggetto della documentazione è richiesta per è una funzione Python. Ma C implementato funzioni sono considerati i comandi incorporati, quindi avrai sempre name(...) come uscita.

Altri suggerimenti

E 'stato 7 anni ma è possibile includere la firma per la funzione C-estensione e le classi .

Python stesso utilizza la Clinica rel="noreferrer"> argomento per generare dinamicamente le firme. Poi alcuni meccanici creano __text_signature__ e questo può essere introspected (ad esempio con help). @MartijnPieters spiegato questo processo abbastanza bene in questa risposta .

Si può effettivamente ottenere la clinica argomento in pitone e di farlo in modo dinamico, ma io preferisco il modo manuale: Aggiunta della firma al docstring:

Nel tuo caso:

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

Ho fatto un uso pesante di questo nel mio pacchetto: iteration_utilities/src . Quindi, per dimostrare che funziona io uso una delle funzioni C-estensione esposti da questo pacchetto:

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

Il docstring per questa funzione è definita questo file .

E 'importante rendersi conto che questo non è possibile per python <3.4 ed è necessario seguire alcune regole:

  • È necessario includere --\n\n dopo la linea di definizione della firma.

  • La firma deve essere in prima linea della docstring.

  • La firma deve essere valido, cioè foo(a, b=1, c) fallisce perché non è possibile definire argomenti posizionali dopo discussioni con default.

  • È possibile fornire una sola firma. Così non funziona se si utilizza qualcosa come:

    foo(a)
    foo(x, a, b)
    --
    
    Narrative documentation
    
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top