docstring ってなに?

ドキュメントです。

「ドキュメント」ってなに?

Python に限らずモジュール、クラス、関数の動作について書かれた説明を、 よく「ドキュメント」と呼んだりします。 例えば標準ライブラリ bisect の「ドキュメント」を例示してみます。

"""Bisection algorithms."""  # <--- モジュールの「ドキュメント」

def insort_right(a, x, lo=0, hi=None):
    """Insert item x in list a, and keep it sorted assuming a is sorted.
    If x is already in a, insert it to the right of the rightmost x.
    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """   # <--- 関数の「ドキュメント」
    
    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if x < a[mid]: hi = mid
        else: lo = mid+1
    a.insert(lo, x)

insort = insort\_right   # backward compatibility

なんで「ドキュメント」を書くの?

答え: 他の人や、あるいは将来の自分に説明するために書きます。

まず、他の方が、書いたコードを読むときは、やっぱりドキュメントが無いと 結構辛い思いをします。

また、自分が、書いたコードでさえ、しばらく経てば何を書いていたかわからなくなります。

このドキュメントの書き方についても PEP 257 で書き方が定められていると言うわけです。

第 1 位 6 か月後の自分のコード - プログラマを悩ませること Top 10
自分が作った昔のコードを見て、顔をゆがめたことはありせんか? なんてバカなんだ! この私がなんでこんなコードを書いたのだろう? 燃やして! 火をつけて燃やして! 安心してください。そう思ったことがあるのはあなただけではありません。

なんで docstring って名前がついてるの?

答え: Python では「ドキュメント」も文字列, str 型の「オブジェクト」だからです。 Python では「トキュメント」は「コメント」ではありません。

ドキュメント document と文字列 string, この2つ合わせて docstring という訳です。

document + string -> docstring

docstring についてもう少し正確に言うと、 関数定義文やクラス定義文の中で、 最初に書かれる str 型のオブジェクトを指しています。

Docstring ってなに? - PEP 257
docstring とは、モジュール, 関数, クラス, メソッドの定義の中で、最初に文として登場する文字列リテラルです。 そのような docstring は オブジェクトの特殊属性 special attribute の __doc__ に代入されます。
What is a Docstring? - PEP 257
A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the __doc__ special attribute of that object.

反対にコメントは str 型のオブジェクトではありません。 そのため変数や属性に代入しようとするとエラーになります。

# SyntaxError になります。
c = # Hello, world!
>>> c = # Hello, world!
  File "stdin", line 1
    c = # Hello, world!
                      ^
SyntaxError: invalid syntax
>>> 

docstring を活用する。

大抵の他の言語では「ドキュメント」は「コメント」として書かれます。 しかし  Python の「ドキュメント」は str 型  のため、 色々と使い回しが効きます。

活用例 1. docstring を活用した「組み込み関数」

組み込み関数とは import しなくても使える関数です。 組み込み関数 help を使いサクッと docstring を閲覧できるようになっています。

# インタラクティブシェルに
# コピペして実行してみてください。
def factorial(n):
    """階乗を求める。 <--- これが docstring
    
    Args:
        n: int 型, 整数
    Returns:
        n の階乗
    """
    if n == 1:
        return 1
    else:
        return n * factorial(n)


# 1) docstring とは
#    関数定義文やクラス定義文で最初に定義された
#    str 型のオブジェクトです。

# 2) この str 型のオブジェクト docstring は
#    特殊属性 special attribute の __doc__ に
#    代入されます。
factorial.__doc__

# 3) help 関数で呼び出すことができます。
#    自分で書いた関数を help で呼び出すようなことはしませんが
#    他の方が書いたコードを help を使って読むことは、よくあります。
help(factorial)
>>>
>>> help(factorial)

---
画面が切り替わります。
---

Help on function factorial in module __main__:

factorial(n)
    階乗を求める。
    
    Args:
        n: int
    Returns:
        n の階乗

---
'q' キーを押すと抜けられます。
最初は抜けられなくて焦ります笑
---
>>>

Python ではドキュメントを書く位置についても「コーディング規約」ではなく 機能として、ここに書いてね、と指定しています。

これはコードのブロックを他の言語のように括弧 { } ではなく、 インデントで分けるように書いたのと考え方が似てるかなと思います。

活用例 2. docstring を活用した「標準ライブラリ」

蛇足ですが docstring を活用した「標準ライブラリ」を2つご紹介します。 せっかく「標準ライブラリ」という言葉を覚えたので使ってみたくなっただけです笑

これらは、気が向いたらちらっと覗いてみてください。 僕も名前を知ってるだけで理解もしてませんし、まだ使ったことがありません。

1つ目は pydoc です。pydoc は docstring からオンラインマニュアルを生成してくれます。 Javadoc に影響されたものなのでしょうか。

2つ目は pydoctest です。pydoctest は docstring に書かれた使用例を元に簡易的なテストを実行してくれます。

PEP 257

PEP 257 では docstring の書き方を定めています。 PEP 8 の docstring 版です。

この文書と PEP 257 (Docstring 規約) は、 Guido が書いたオリジナルのPythonスタイルガイドのエッセイと、 Barry のスタイルガイドに少し追記したものをまとめたものです。
Python コードのスタイルガイド - PEP 8

PEP 257 そのものの解説は、差し控えさせていただきたいと思います。 ここでは docstring というものの存在だけ知っていただければと思いました。 自分は pydocstyle というツールをエディタに適用させて、覚えました。