Libreria per l'inserimento automatico di docstring in pitone in stile Google


9

Sto cercando un pacchetto elisp che inserisca automaticamente la documentazione di Python per un metodo. Ho trovato un pacchetto, che è molto vicino al mio scopo. Ma è nel testo ricostruito, non nello stile di Google.

sphinx-doc.el https://github.com/naiquevin/sphinx-doc.el

Descrivere argomenti in docstrings (guida allo stile di Google python) https://www.chromium.org/chromium-os/python-style-guidelines#TOC-Describing-arguments-in-docstrings

La mia aspettativa è quando chiamo M-x sphinx-doc-googleall'interno della seguente funzione,

def some_function(a, b, c):

Ho bisogno di un risultato come questo.

def some_function(a, b, c):
    """
    Args:
        a:
        b:
        c:
    Returns:
    """

So che non è difficile da attuare da solo. Voglio solo porre questa domanda per evitare la reinvenzione.


Non penso che ci sia. Questo stile non è esattamente popolare nella più ampia comunità Python per quanto ne so.

Grazie. Ho pensato che fosse popolare perché l'impostazione predefinita della regola di inserimento automatico dei documenti di PyCharm è lo stile di Google. Ho usato un testo ricostruito per un po ', ma non è molto leggibile dall'uomo. :(
sy2,

Risposte:


9

Uso il pacchetto chiamato yasnippet per qualcosa di simile a questo. Dopo alcune piccole modifiche l'ho adattato per utilizzare invece lo stile docstring di Google:

Google in stile Python yasnippet

Si noti tuttavia che richiede alcune impostazioni:

Lo snippet stesso deve eseguire un codice elisp di utilità per generare il testo. Questo è in genere risolto creando un file chiamato .yas-setup.elcon il codice all'interno della python-modedirectory dello snippet. Tuttavia è anche possibile posizionare il codice da qualche parte all'interno del tuo .emacs.

Il codice per lo snippet è:

# -*- mode: snippet -*-
# Insert Google style docstring and function definition.
# name: Python Google style Docstring
# key: defg
# type: snippet
# contributor: Xaldew
# --
def ${1:name}($2):
    \"\"\"$3
    ${2:$(python-args-to-google-docstring yas-text t)}
    ${5:Returns:
        $6
}
    \"\"\"
    ${0:$$(let ((beg yas-snippet-beg)
                (end yas-snippet-end))
        (yas-expand-snippet
          (buffer-substring-no-properties beg end) beg end
              (quote ((yas-indent-line nil) (yas-wrap-around-region nil))))
            (delete-trailing-whitespace beg (- end 1)))}

Il codice per il .yas-setup.elè:

(defun python-args-to-google-docstring (text &optional make-fields)
  "Return a reST docstring format for the python arguments in yas-text."
  (let* ((indent (concat "\n" (make-string (current-column) 32)))
         (args (python-split-args text))
     (nr 0)
         (formatted-args
      (mapconcat
       (lambda (x)
         (concat "   " (nth 0 x)
             (if make-fields (format " ${%d:arg%d}" (cl-incf nr) nr))
             (if (nth 1 x) (concat " \(default " (nth 1 x) "\)"))))
       args
       indent)))
    (unless (string= formatted-args "")
      (concat
       (mapconcat 'identity
          (list "" "Args:" formatted-args)
          indent)
       "\n"))))

Si noti che python-split-argsè fornito dagli snippet standard . Vale a dire: https://github.com/AndreaCrotti/yasnippet-snippets/tree/master Tuttavia, li ottieni di default quando installi il pacchetto package.el.

Con tutto impostato correttamente, dovresti essere in grado di scrivere "defg" seguito da Tabper espandere lo snippet (vedi l'immagine per un esempio).

Esiste ancora un problema con l'utilizzo di questo rientro nidificato, ad esempio all'interno di classi o come funzioni nidificate. In quei casi, per qualche motivo la dotstring viene indentata erroneamente un tempo extra. Aggiornerò questo post se riesco a risolverlo.

Lo snippet ora dovrebbe funzionare all'interno di altri ambiti vietando yasnippetdi rientrare automaticamente nella seconda espansione.


1
Domanda stupida, ma come posso effettivamente farlo funzionare su una funzione esistente? Scrivo defge mi dà una nuova funzione denominata namesenza argomenti, e non riesco a vedere alcun modo per automatizzarlo aggiornando il docstring mentre cambio quella funzione. Quando guardo il mio buffer Messaggi, vedo yas--update-mirrors: Wrong type argument: stringp, (python-args-to-google-docstring).
Autumnsault,

1
L'ho incontrato oggi anche in un altro dei miei frammenti, penso che potrebbe essere un bug yasnippet. Dovrò comunque creare un esempio minimo per segnalarlo correttamente. Potrebbe anche essere che concatenare frammenti in questo modo non sia più supportato, ma spero che non lo sia.
Xaldew,

Questo è ancora un problema? Non sono più in grado di replicare l'errore sopra usando l'ultimo Emacs / yasnippet.
Xaldew,

Sì, è ancora problematico. Sto usando emacs 24.5.1 (l'ultima versione di Ubuntu) e l'ultima versione di yasnippet.
Autumnsault,

1
@AstroFloyd È corretto, il codice per .yas-setup.eldovrebbe finire nella stessa directory della directory snippet per la modalità attualmente attiva. Che è ~/.emacs.d/snippets/python-mode/.yas-setup.elper la modalità Python come hai sottolineato.
Xaldew,

3

Come ha detto Lunaryorn, lo stile non è popolare e non ci sono pacchetti.

Tuttavia esiste un pacchetto chiamato sphinx-doc che genererà una stringa doc in formato sfinge ( demo ).

È possibile modificare quel pacchetto per generare stringhe in base alle proprie esigenze.


-1

Puoi usare questo codice.

Sposta il cursore sul nome della tua funzione e poi su F9.

 (defun chomp (str)
        "Chomp leading and tailing whitespace from STR."
        (let ((s (if (symbolp str) (symbol-name str) str)))
          (replace-regexp-in-string
           "\\(^[[:space:]\n]*\\|[[:space:]\n]*$\\)" "" s)))
 (defun get-function-definition(sentence)
    (if (string-match "def.*(.*):" sentence)
        (match-string 0 sentence)))
 (defun get-parameters(sentence)
    (setq y (get-function-definition sentence))
    (if y
        (if (string-match "(.*)" y)
            (match-string 0 y))))
 (autoload 'thing-at-point "thingatpt" nil t) ;; build-in librairie
 (defun python-insert-docstring()
        (interactive)
        (setq p (get-parameters (thing-at-point 'sentence)))
        (forward-line 1)
        (insert "    \"\"\"\n")
        (insert "\tArgs:\n")
        (setq params (split-string p "[?\,?\(?\)?\ ]"))
        (while params
          (if (/= (length (chomp (car params))) 0)
              (progn
                (insert "        ")
                (insert (chomp (car params)))
                (insert ": \n")))
          (setq params (cdr params)))
        (insert "    Returns:\n    \"\"\"\n"))
      (global-set-key (kbd "<f9>") 'python-insert-docstring)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.