LoginSignup
55
35

More than 3 years have passed since last update.

型ヒントのお試し

Last updated at Posted at 2019-12-03

概要

PEP 484: Type Hints がPython3.5で導入されました。詳しくは、公式ドキュメント 型ヒントのサポート を参照してください。

最近、コミュニティ内でも導入している話を多く聞くようになりました。私も今後のプロジェクトで導入を進めたいと思い、自身の勉強と他の人に説明するときの参考資料にするためにここにまとめます。

型ヒントは、Pythonの文法としてPython3.5以降で導入されました。

  • ヒントなので、実行時には何も影響を与えない
  • 組み込みの公式ツールはない

ツール

  • mypyというデファクトのチェックツールがある(pipでインストール可能)
  • PyCharmなどのエディタが対応し、コード補間が強力になり、チェックもしてくれる
  • ヒントを記載した場所(モジュール単位でも関数単位でも)のみで有効になる
  • ヒント書けば書くほどコード補間が効き、チェックもしてくれる

mypyのチートシート

mypyのインストール

(env) $ pip install mypy

mypyでチェック

(env) $ mypy モジュール名

型ヒント定義例

例として、すべて整数(int)型で示します。

変数定義


a: int = 10
a: int
a = 10

関数の引数定義

def f(a: int):
    pass

def f(a: int = 10):
    pass

関数の戻り値定義


def f(a) -> int:
    return 10

def f(a: int, b: int = 10) -> int:
    return a + b

型定義

データ型で定義

名称
整数 int
浮動小数点数 float
文字列 str
バイト型 bytes
真理値 bool
None None

コンテナ系

コンテナ系は、内包する型を指定するので、 list[int] などと表記を行いたい。しかし、これはPythonの文法エラーとなってしまう。その為に、typingでは専用の型を準備している


from typing import List, Tuple, Dict, Set
名称 定義例
リスト List List[int]
タプル Tuple Tuple[int, int] / Tuple[int, ...]
辞書 Dict Dict[str, int]
セット Set Set[int]

特殊な型

from typing import Any
名称 定義例
なんでもいい Any Any

from typing import Callable, Iterator, MutableMapping
名称 定義例
呼び出し可能 Callable Callable[[int, float], bool]
繰り返し可能 Iterator Iterator[int]
辞書のような挙動 MutableMapping MutableMapping[str, int]

その他

Optional

Optionalは、指定の型 or Noneを、許容する型です。
例えば、整数とNoneのいずれかを許容する場合は、 Optional[int] とします。

以下の様なケースで利用します。


from typing import Optional

def f1(a: int, b: int) -> Optional[int]:
    if b == 0:
        return None
    return a // b

便利なのは以下の様に使えるからです。


def f2(c: Optional[int]) -> int:
    if c is None:
        c = 0
    return c + 100

上記のケースを以下の様に記載すると、mypyがエラーを通知します。


def f2(c: Optional[int]) -> int:
    return c + 100
$ mypy sample.py 
sample.py:**: error: Unsupported operand types for + ("None" and "int")
sample.py:**: note: Left operand is of type "Optional[int]"
Found 1 error in 1 file (checked 1 source file)

つまり、 if c is None を行うことで、cがNoneの時を加え、それによりそれ以降の行では、変数c
は、整数型(int)であることが確定しているので、問題なく処理ができることを保証しています。

Union

Unionは、2つのいずれかの型を示すことができます。
例えば、整数型 or 文字列型 と言った場合に、 Union[int, str] と指定します。

以下の様に引数を受け取るときに、整数か文字列かが分からないような場合に使い、 isinstance を使って処理を分けることで、上記のOptional同様に、変数の型を確定させる事ができます。


from typing import Union

def f3(d: Union[int, str]) -> str:
    if not isinstance(d, str):
        d = str(d)
    return d.upper()

ここでは、 if not isinstance(d, str): として、変数dが文字列型(str)でないときに、文字列に変換する処理を入れて処理を継続しています。 return d.upper() で、 d が文字列であることが分かっているので、安全に大文字に変換する文字列型のメソッドが使えています。

int と float

intと指定してfloatは入れられませんが、その反対のfloatと指定してintを入れる事ができます。
以下の場合、 num4だけがエラーがでます。


num1: float = 1.0
num2: float = 1
num3: int = 1
num4: int = 1.0  # これはエラーとなる
$ mypy sample/sample.py 
sample.py:**: error: Incompatible types in assignment (expression has type "float", variable has type "int")

これは、intをfloatに自動変換することができるが、その反対のfloatをintにすると情報を失うことがあることに起因しているそうです。

55
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
35