NumPy スタイルの docstring

2020年3月14日

はじめに

Sphinx でドキュメント化できる NumPy スタイルの docstring について。

NumPy スタイルの docstring

docstring は、Python でクラスや関数などの説明を書くためのものである。以下のように書く。

def secant(x0, x1, f, eps=1e-15, maxi=100):
    """
    セカント法を用いて方程式 f(x) = 0 を満たす x を求める
    """
    x_i = x0
    x_i_1 = x1
    f_i_1 = f(x_i_1)
    x_new = x_i

    for i in range(maxi):
        f_i = f(x_i)

        if abs(f_i) < eps or abs(x_i - x_i_1) < eps:
            break

        x_new = x_i - f_i*(x_i - x_i_1)/(f_i - f_i_1)

        x_i_1 = x_i
        f_i_1 = f_i
        x_i = x_new

    return x_new

docstring にはいくつかのスタイルがあり、ここでは NumPy スタイルを見る。

引数の説明を書く場合は、次のようにする。

def secant(x0, x1, f, eps=1e-15, maxi=100):
    """
    セカント法を用いて方程式 f(x) = 0 を満たす x を求める

    Parameters
    ----------
    x0 : float
        初期値1
    x1 : float
        初期値2
    f : function
        方程式 f(x) = 0 の f(x) を表す関数
    eps : float, default 1e-15
        打ち切りしきい値
    maxi : int, default 100
        最大繰り返し回数
    """

返り値の説明は、次のように書く。

def secant(x0, x1, f, eps=1e-15, maxi=100):
    """
    ...

    Returns
    -------
    x : float
        方程式 f(x) = 0 を満たす x
    """

使用例を書くこともできる。

def secant(x0, x1, f, eps=1e-15, maxi=100):
    """
    ...

    Examples
    --------
    >>> secant(0., 2., lambda x: x**2 - 2.)
    1.4142135623730954
    """

クラスの説明は次のように書ける。

class Secant:
    """
    セカント法

    Attributes
    ----------
    eps : float
        打ち切りしきい値
    maxi : int
        最大繰り返し回数

    Examples
    --------
    >>> s = Secant()
    >>> s.solve(0., 2., lambda x: x**2 - 2.)
    1.4142135623730954
    """

    def __init__(self):
        self.eps = 1e-16
        self.maxi = 100

    def solve(self, x0, x1, f):
        """
        方程式 f(x) = 0 を満たす x を求める

        Parameters
        ----------
        x0 : float
            初期値1
        x1 : float
            初期値2
        f : function
            方程式 f(x) = 0 の f(x) を表す関数

        Returns
        -------
        x : float
            方程式 f(x) = 0 を満たす x
        """
        x_i = x0
        x_i_1 = x1
        f_i_1 = f(x_i_1)
        x_new = x_i

        for i in range(self.maxi):
            f_i = f(x_i)

            if abs(f_i) < self.eps or abs(x_i - x_i_1) < self.eps:
                break

            x_new = x_i - f_i*(x_i - x_i_1)/(f_i - f_i_1)

            x_i_1 = x_i
            f_i_1 = f_i
            x_i = x_new

        return x_new