関数アノテーションと型ヒント,変数アノテーション,docstring

「あれ?この関数の引数と戻り値なんだったっけ…(´Д` ;)」

という事態にしばしば陥ったため,戒めのためにメモ.

関数アノテーション(function annotations)

普通,Pythonでは関数は次のように書く.

def func(x, y):
    return x + y

pythonは動的型付け言語であるため,xとかyの型は指定されていない.

これにより,コードが楽に書ける一方で,コードを書いた本人ですら,引数や戻り値の型を後で忘れてしまって大混乱,という事態になりかねない.

そこで,Python3.0以降,次のように注釈(アノテーション)をつけることができるようになった.

def func(x: "int", y: "int") -> "int":
    return x + y

このように注釈をつけても,関数の機能にはなんら影響を与えないし,xyにstr型の値を代入してもエラーにはならない.

次のように自由に注釈がつけられる.

def func(x: "ご当地キャラ", y: "悪魔") -> "くまモン":
    return x + y

単に,コードを読む人に対してわかりやすくなる,という以上の効果はない.

型ヒント(type hints)

上の書き方だと自由に注釈を書くことができたけど,PEP484で標準の記述方法が規定された.

例えば次のようにも書けるようになった.

def func(x: int, y: int) -> int:
    return x + y
from typing import List

def sum_func(x: List[float]) -> float:
    return sum(x)

記述できる型としては

  • int
  • float
  • str
  • bool
  • complex

などが使える.

また,Python3.5以降で追加されたtypingモジュールを利用することにより,以下のような型アノテーションが書けるようになる:

  • List[X]: 要素がXという型からなるリスト
  • Dict[X, Y]: キーがX, 値がYという型からなる辞書
  • Tuple[X, Y]: 要素がX, Yという型からなるタプル
  • Union[X, Y]: XかYの型
  • Any: 任意の型

あくまで注釈なので,これらを書いても型のチェックは行われない.

変数アノテーション(variable annotations)

変数に対しても型ヒントとかGolang的な書き方がしたい場合,

a: int = 100

のような書き方がPython3.6以降できるようになった

ただし,これも型チェックがされるわけではないので,

b: str = 100

のように書いても,相変わらずpythonは型を自動的に推定してbの型はintだと認識するので注意.

np.arrayの場合どうしよう?

一応,

c: np.ndarray = np.array([1,2,3])

のように変数アノテーションをつけることはできる.

docstringに書けばいいじゃない

Pythonでは,関数やクラスなどの記述の,先頭の文字列はdocstringドキュメンテーション文字列)として扱われ,これを後でsphinxなどで文書化して仕様書を自動生成,という素晴らしい手順もあります.

docstringの書き方は色々あるらしく,

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

の中でも,たとえばGoogleスタイルで注釈を書くと,

def func_google(arg1, arg2):
    """関数の説明

    Args:
        arg1 (int): 引数arg1の説明
        arg2 (str): 引数arg2の説明

    Returns:
        bool: 戻り値の説明

    """
    return True

のようになる.

docstringは,その関数の__doc__に保存されている:

print(func_google.__doc__)
関数の説明

    Args:
        arg1 (int): 引数arg1の説明
        arg2 (str): 引数arg2の説明

    Returns:
        bool: 戻り値の説明

ここまで書けば,関数アノテーションを使う必要はないだろう.

変数アノテーションと組み合わせて,リーダブルかつデバッグしやすいコードを心がけたい.

参考にさせていただいたページ

Python と型アノテーション

Pythonの関数アノテーションと型ヒント、typingモジュール | note.nkmk.me

26.1. typing — 型ヒントのサポート — Python 3.6.5 ドキュメント

What’s New In Python 3.6 — Python 3.6.5 ドキュメント

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