Pythonのdocstring(ドキュメンテーション文字列)の書き方

Pythonでは関数やクラスなどの定義の先頭に文字列を記述するとdocstring(ドックストリング、ドキュメンテーション文字列)として扱われる。 IDEやエディタによってはキーボードショートカットでdocstringを表示させて内容を確認できます。またPyCharmなどでは、docstringの情報をもとに静的解析して警告を出してくれる。 docstringの中に入出力例を書いてテストを実行することもできます。 ここでは以下の内容について説明します。

docstringの表示・出力方法 __doc__属性 組み込み関数help() IDEやエディタでの表示 関数、クラスなどでのdocstringの基本的な書き方 doctestによるテスト 引数や返り値などの書き方のスタイル reStructuredText(reST)スタイル NumPyスタイル Googleスタイル 関数アノテーション

docstringの表示・出力方法

以下のように関数にdocstringを記述します。docstring自体の書き方は後述します。

def my_func():
    """docstring-test
    line1
    line2
    line3
    """

__doc__属性

docstringは__doc__属性に文字列として格納されています。print()で出力できます。

print(my_func.__doc__)
# docstring-test
#     line1
#     line2
#     line3

print(type(my_func.__doc__))
# <class 'str'>

組み込み関数help()

Jupyter Notebookやターミナルでの対話環境(pythonまたはpython3コマンドで起動するPythonインタプリタ)で組み込み関数help()に対象のオブジェクトを渡して実行するとそのdocstringが対話的ヘルプシステムで出力されます。

  1. 組み込み関数 help() — Python 3.6.5 ドキュメント
help(my_func)
# Help on function my_func in module __main__:
# my_func()
#     docstring-test
#     line1
#     line2
#     line3

ターミナルでの対話型ヘルプシステムはqで終了できます。

IDEやエディタでの表示

IDEやエディタによってはdocstringの内容をショートカットキーなどで表示して確認できます。いくつか例を示す。 Jupyter Notebook Jupyter Notebookでは対象の関数などにカーソルを合わせてshift + tabでツールチップにdocstringが表示されます。さらにshiftを押したままtabを連打すると詳細表示、分割表示と表示方式が変化します。

VS Code VS Codeではマウスポインタを対象の関数などに合わせるとツールチップにdocstringが表示されます。カーソルを合わせてショートカットcommand + k, command + i(またはcontrol + k, control + i)でも表示できます。

関数、クラスなどでのdocstringの基本的な書き方

docstringの基本的な書き方を示す。引数や返り値などのスタイルは後述します。 定義の先頭にトリプルクォート('''または""")で囲んで文字列を記述するのが基本。

def my_func():
    """docstring-test
    line1
    line2
    line3
    """

文字列であればいいので、複数行でなければトリプルクォートではなくシングルクォート'やダブルクォート"でもdocstringとなります。ただし、一行であっても慣例的にトリプルクォートが使われることが多い。

def my_func2():
    'docstring-test'

print(my_func2.__doc__)
# docstring-test

定義の先頭でないとdocstringとならない。文字列の前に式などが記述されているとダメ。

def my_func_error():
    a = 100
    """docstring-test
    line1
    line2
    line3
    """

print(my_func_error.__doc__)
# None

クラスでも同じです。定義の先頭に文字列を記述します。

class MyClass:
    """docstring-test
    line1
    line2
    line3
    """

print(MyClass.__doc__)
# docstring-test
#     line1
#     line2
#     line3

doctestによるテスト

docstringの中に入出力例を書くと、標準ライブラリのdoctestモジュールを使ってテストを実行することができます。

26.3. doctest — 対話的な実行例をテストする — Python 3.6.5 ドキュメント

簡単なサンプルは以下の通り。

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    15
    '''

    return a + b

テストの実行方法などの詳細は

引数や返り値などの書き方のスタイル

docstingの中には関数の引数や返り値の説明や型などを記述するが、書き方のフォーマットは特に統一されていません。

coding style - What is the standard Python docstring format? - Stack Overflow

代表的な3つのスタイルの例を示す。

reStructuredText(reST)スタイル NumPyスタイル Googleスタイル

読む人が理解できるスタイルであれば神経質になる必要はないと思うが、所属組織やプロジェクトのコーディング規約がなければこれらのスタイルを参考にするといいと思います。 代表的なスタイルはドキュメント化やIDEやエディタでの補助機能に対応しているという利点もあります。 reStructuredTextスタイルだけでなく、NumPyスタイルとGoogleスタイルのdocstringもSphinxを使ってドキュメントを自動的に生成(html化)することができます。

sphinx.ext.napoleon – NumPy および Google スタイルの docstring をドキュメントに取り込む — Sphinx 1.5.6 ドキュメント

IDEやエディタ(およびプラグイン)によっては対応しているスタイルであれば型のヒントの表示やエラーチェックをしてくれるものもあります。 例えばPyhtonの統合開発環境であるPyCharmでは3つすべてのスタイルに対応しています。

Docstringsを使用した型の指定 - 公式ヘルプ | PyCharm Python 統合ツール - 公式ヘルプ | PyCharm

また、Python3.0以降では関数アノテーション(Function Annotations)という仕組みによって、関数の引数や返り値にアノテーション(注釈)を記述することができます。後述します。

reStructuredText(reST)スタイル

def func_rest(arg1, arg2):
    """Summary line.

    :param arg1: Description of arg1
    :type arg1: int
    :param arg2: Description of arg2
    :type arg2: str
    :returns: Description of return value
    :rtype: bool
    """
    return True
```python


reSTスタイルはサードパーティライブラリRequestsなどで採用されています。以下が実際のコード。
```python
def add_dict_to_cookiejar(cj, cookie_dict):
    """Returns a CookieJar from a key/value dictionary.

    :param cj: CookieJar to insert cookies into.
    :param cookie_dict: Dict of key/values to insert into CookieJar.
    :rtype: CookieJar
    """

    return cookiejar_from_dict(cookie_dict, cj)

NumPyスタイル

numpydocというNumPyのドキュメント用のSphinx拡張機能に対応したスタイル。

numpydoc – Numpy’s Sphinx extensions — numpydoc v0.9.dev0 Manual NumPyスタイルPython Docstringsの例 — Sphinx 1.5.6 ドキュメント

def func_numpy(arg1, arg2):
    """Summary line.

    Extended description of function.

    Parameters
    ----------
    arg1 : int
        Description of arg1
    arg2 : str
        Description of arg2

    Returns
    -------
    bool
        Description of return value
    """
    return True

pandasの実際のコード例は以下の通り。

def safe_sort(values, labels=None, na_sentinel=-1, assume_unique=False):
    """
    Sort ``values`` and reorder corresponding ``labels``.
    ``values`` should be unique if ``labels`` is not None.
    Safe for use with mixed types (int, str), orders ints before strs.

    .. versionadded:: 0.19.0

    Parameters
    ----------
    values : list-like
        Sequence; must be unique if ``labels`` is not None.
    labels : list_like
        Indices to ``values``. All out of bound indices are treated as
        "not found" and will be masked with ``na_sentinel``.
    na_sentinel : int, default -1
        Value in ``labels`` to mark "not found".
        Ignored when ``labels`` is None.
    assume_unique : bool, default False
        When True, ``values`` are assumed to be unique, which can speed up
        the calculation. Ignored when ``labels`` is None.

    Returns
    -------
    ordered : ndarray
        Sorted ``values``
    new_labels : ndarray
        Reordered ``labels``; returned when ``labels`` is not None.

    Raises
    ------
    TypeError
        * If ``values`` is not list-like or if ``labels`` is neither None
        nor list-like
        * If ``values`` cannot be sorted
    ValueError
        * If ``labels`` is not None and ``values`` contain duplicates.
    """

Googleスタイル

GoogleのPythonスタイルガイドの中で定められているdocstringのスタイル。

styleguide/pyguide.md at gh-pages · google/styleguide GoogleスタイルのPython Docstringsの例 — Sphinx 1.5.6 ドキュメント

def func_google(arg1, arg2):
    """Summary line.

    Extended description of function.

    Args:
        arg1 (int): Description of arg1
        arg2 (str): Description of arg2

    Returns:
        bool: Description of return value

    """
    return True

TensorFlowの実際のコード例は以下の通り。

def broadcast_dynamic_shape(shape_x, shape_y):
  """Returns the broadcasted dynamic shape between `shape_x` and `shape_y`.

  Args:
    shape_x: A rank 1 integer `Tensor`, representing the shape of x.
    shape_y: A rank 1 integer `Tensor`, representing the shape of y.

  Returns:
    A rank 1 integer `Tensor` representing the broadcasted shape.
  """
  return gen_array_ops.broadcast_args(shape_x, shape_y)

関数アノテーション

Python3.0以降では関数アノテーション(Function Annotations)という仕組みによって、関数の引数や返り値にアノテーション(注釈)となる式を記述することができます。

def func_annotations_type(x: str, y: int) -> str:
    return x * y

関数アノテーションは単なる注釈なので、例えば上の例のように型を記述した場合でも実行時にチェックされたりはしないが、IDEやエディタによってはその情報をもとに処理を行うものもあります。 詳細は

関数アノテーションとdocstringは二者択一ではなく、型は関数アノテーション、詳しい説明文はdocstringというように併用して記述する例が多い。

Last Updated: 6/26/2019, 10:34:03 PM