GoogleスタイルでPython docstringを自動的に挿入するためのライブラリ


8

メソッドのPython docstringを自動的に挿入するelispパッケージを探しています。私の目的に非常に近いパッケージを見つけました。ただし、Googleスタイルではなく、reStructuredテキストです。

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

docstringsでの引数の記述(Google pythonスタイルガイド) https://www.chromium.org/chromium-os/python-style-guidelines#TOC-Describing-arguments-in-docstrings

私の期待はM-x sphinx-doc-google、次の関数内で呼び出すときです。

def some_function(a, b, c):

このような結果が必要です。

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

自分で実装するのは難しくないことはわかっています。再発明を避けるためにこの質問をしたいだけです。


あるとは思いません。このスタイルは、私が知る限り、大規模なPythonコミュニティではあまり人気がありません。
lunaryorn

ありがとう。PyCharmの自動docstring挿入ルールのデフォルト設定はGoogle風なので人気だと思いました。私はしばらくの間reStructuredテキストを使用していましたが、それはあまり人間が読めるものではありません。:(
sy2

回答:


8

これに似たものには、yasnippetというパッケージを使用します。いくつかのマイナーな変更の後、代わりにGoogleのdocstringスタイルを使用するように変更しました。

GoogleスタイルのPython yasnippet

ただし、いくつかの設定が必要です。

スニペット自体は、テキストを生成するためにいくつかのユーティリティelispコードを実行する必要があります。これは通常.yas-setup.elpython-modeスニペットディレクトリ内のコードで呼び出されるファイルを作成することで解決します。ただし、.emacs代わりにコードを自分の内部のどこかに配置することもできます。

スニペットのコードは次のとおりです。

# -*- 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)))}

のコード.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"))))

標準のスニペットpython-split-argsによって提供されることに注意してください。すなわち:https : //github.com/AndreaCrotti/yasnippet-snippets/tree/masterただし、を介してパッケージをインストールすると、デフォルトでこれらが取得されます。package.el

すべてが適切に設定されていれば、 "defg"に続けTabてスニペットを展開できます(例については画像を参照してください)。

これをネストされたインデントの内側、たとえばクラス内またはネストされた関数として使用することにはまだ問題があります。これらの場合、何らかの理由でdocstringが誤って余分にインデントされます。なんとか修正できたら、この投稿を更新します。

yasnippet2番目の展開の自動インデントを禁止することで、スニペットが他のスコープ内で機能するようになりました。


愚かな質問ですが、実際にこれを既存の関数でどのように機能させるのですか?入力するdefgname、引数なしの名前の新しい関数が表示されます。その関数を変更すると、docstringの更新を自動化する方法がわかりません。メッセージバッファを見ると、が表示されていますyas--update-mirrors: Wrong type argument: stringp, (python-args-to-google-docstring)
Autumnsault 2017年

1
私は実際に私のスニペットの他にも、この今日遭遇、私は考えて、それはバグかもしれyasnippet。それを正しく報告するには、最小限の例を作成する必要があります。また、この方法でのスニペットのチェーンがサポートされなくなった可能性もありますが、そうではないことを願っています。
Xaldew 2017年

これはまだ問題ですか?最新のEmacs / yasnippetを使用して上記のエラーを再現することはできなくなりました。
Xaldew 2017年

ええ、それはまだ問題があります。emacs 24.5.1(最新のUbuntuバージョン)と最新バージョンのyasnippetを使用しています。
Autumnsault

1
@AstroFloyd正解です。コード.yas-setup.elは、現在アクティブなモードのスニペットディレクトリと同じディレクトリにあるはずです。あなたが~/.emacs.d/snippets/python-mode/.yas-setup.el指摘したように、これはpythonモード用です。
Xaldew、

3

lunaryornが述べたように、スタイルは人気がなく、パッケージはありません。

ただし、sphinx形式(デモ)でドキュメント文字列を生成するsphinx-docというパッケージがあります。

必要に応じて、そのパッケージを変更して文字列を生成できます。


-1

このコードを使用できます。

カーソルを関数名に移動し、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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.