1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonの型ヒントを学ぶ

Last updated at Posted at 2023-08-10

これまで、あまりPythonに型の必要性を感じてなかったので、うっかりスルーしてきたのですが、改めて学んでみました。

Pythonで型ヒントの書き方

Pythonの型ヒントの使用例は以下の通りです。

# 変数に型ヒントを指定する
name: str = "Luca"
age: int = 22

# 関数に型ヒントを指定する
def greet(name: str, age: int) -> str:
    return f"Hello, {name}({age})"

print(greet(name, age))

ListやDict型の型ヒント

ListやDict型の型ヒントを使うときは、typingモジュールを使います。

from typing import List, Tuple, Dict

# 関数に型ヒントを指定する
def list_to_str(items: List) -> str:
    lines = ""
    for it in items:
        lines += it + '\n'
    return lines

print(list_to_str(['a', 'b', 'c']))

静的型チェックをしたい時

実際のところ、型が間違っていても、型はあくまでもヒントであり、特にエラーが出るというわけではありません。以下は、List[str]を求める関数list_to_strを定義しましたが、List[int]型のリストを与えてもエラーは出ません。

type_err.py
from typing import List, Tuple, Dict

# 引数がList[str]を取ることを明示
def list_to_str(items: List[str]):
    for it in items:
        print(it)

# List[int]を指定したがエラーは出ない
list_to_str([10,20,30])

そこで登場するのが、静的型チェックを行うパッケージmypyです。以下のようにして、mypyをインストールします。

$ python3 -m pip install mypy

そして、上記のプログラム「type_err.py」を以下のようにチェックします。すると、エラーを表示します。

$ mypy type_err.py
type_err.py:9: error: List item 0 has incompatible type "int"; expected "str"  [list-item]
type_err.py:9: error: List item 1 has incompatible type "int"; expected "str"  [list-item]
type_err.py:9: error: List item 2 has incompatible type "int"; expected "str"  [list-item]
Found 3 errors in 1 file (checked 1 source file)
D

ユニークな型を定義して使う場合

typingのNewTypeを使うと、既存型を指定して、新たな型を定義できます。

from typing import NewType

# NewTypeを使って、型を定義
UserId = NewType('UserId', int)
ItemId = NewType('ItemId', int)

これを使うと、意図的に異なる意味や目的を持つデータを区別することができることです。

下記の例では、a_idなどという中途半端な変数名を使うことにしたため、UserIdとItemIdを間違えて関数を呼び出しています。

err.py
from typing import NewType

# NewTypeを使って、型を定義
UserId = NewType('UserId', int)
ItemId = NewType('ItemId', int)

# 引数が UserId を取ることを明示
def get_user_name(user_id: UserId) -> str:
    if user_id == 1:
        return 'Luca'
    else:
        return 'Unknown user'

# ItemId の変数を宣言
a_id: ItemId = 1
# UseIdを指定するべきところを間違えて ItemId を渡してしまう!!
print(get_user_name(a_id))

上記のプログラム、実行すると・・・正しく動いてしまいます。エラーは1ミリも出ません。
しかし、静的型チェックを行うと・・・下記のように正しくエラーを出してくれます。

$ mypy err.py
err.py:15: error: Incompatible types in assignment (expression has type "int", variable has type "ItemId")  [assignment]
err.py:17: error: Argument 1 to "get_user_name" has incompatible type "ItemId"; expected "UserId"  [arg-type]
Found 2 errors in 1 file (checked 1 source file)

Visual Studio Codeで型ヒントを活用するヒント

なお、VSCodeで型ヒントをもっと積極的に使うには、Python:Linterでmypyを選択すると良いです。

以下のように、型ヒントに沿ってVSCodeが間違いを指摘してくれるようになります。

lint-type-error.png

まとめ - 型を付けるとなにが良いのか?

  • 型をつけておくと、エディタやIDEを使う時に、入力補完が利くのでとても便利です。
  • 型をつけると、mypyを使って静的型チェックが可能になって便利です。
  • 型を付けると、コードの品質を向上させることが可能です。
1
4
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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?