Pythonで型指定するTypingの基本的な使い方まとめ

 今回は基本的なPythonのTypingについてまとめました。

 今回記載するルールをすべて知ってたらTypingでそんなに困ることないと思います。

 TypeGuardやLiteralなど応用的なやつは別記事で書いているのでそちらもよかったら見てみてください。

Typingとは?


 Pythonでも型を記載することができます。その仕組みがTyping。

 PyCharmなどのエディタだと指定したtypingとマッチしないと警告を出してくれたりします。

 ただし、実行時にチェックしてくれるわけではないので、あくまでコーディング中のみ使えるようなものです。

 それでも指定するとコードの読みやすさや保守性は大幅に向上すると思います。

基本的なTypingの書き方、パッケージ


 変数の型はこんな感じ。

変数名: 型 = 値
self.変数名: 型 = 値  # メンバ変数も同じ

 関数のType hintはこのようなルールです。

def 関数名(引数名 : 型,....) -> <戻り値の型>:
  return ~

 ListやDict、Optionalや関数オブジェクトを表すCallableはtypingパッケージのimportが必要です。標準で入っているのでpip installなどは必要ありません。

 from typing import List, Callableなどが必要になってきます。

基本的な組み込み型

 まずはstr, int, float型。

 単純にstr, int, floatを記載するだけ。

 ちなみにどの型でも許容する場合はanyを指定する。

def test_func(str_arg: str, int_arg: int, float_arg: float) -> any:
    return "test", "hoge"

List, Tuple, Set, Dict型のTyping


 まずはListとSet。

 List[リスト要素の型]という形式。Setも同様でSet[セット要素の型]。

 typingのList, Setをimportする必要がある。

from typing import List, Set

def sum_list(ls: List[int]) -> int:
  result = 0
  for num in ls:
    result += num
  return result

set_val: Set[int] = {1, 2, 3, 4, 5, 6}

 次にTuple。

 Tuple[1つ目の値の型, 2つ目の値の型….]という形式。typingのTupleをimportする必要がある。

from typing import Tuple

# 面積と周囲長を計算する関数
def calc_area_and_perimeter(size: Tuple[int, int]) -> Tuple[int, int]:
  return size[0] * size[1], size[0]*2 + size[1]*2

 次にDict。

 Dict[keyの型, valueの型]という形式。typingのDictをimportする必要がある。

from typing import Dict

key_value: Dict[str, int] = {"aaa": 1, "bbb": 2}

自作ClassのTyping


 自作Classは普通にClassを指定するだけ。

 また、staticmethodで自身のClassオブジェクトを返したい場合は’Class名’にする必要がある。

class CustomClass:
    def __init__(self, a: str):
        self.a = a

    @staticmethod
    def create() -> 'CustomClass':
        return CustomClass("from create function.")


custom_class_obj: CustomClass = CustomClass.create()

複数の型を許容する場合 – Union型


 Union[許容する型1, 許容する型2,…]といった感じで複数の型を許容することを表すことができる。

 from typing import Unionが必要。

from typing import Union, List, Tuple


def return_head_and_tail(arg: Union[str, List: any]) -> Tuple[any, any]:
    return arg[0], arg[-1]


return_head_and_tail([1, 2, 3])
return_head_and_tail("hogehoge")

Noneを許容する場合 – Optional型


 Noneも許容する型は、Optional[本来期待する型]にすることで表すことができる。

 from typing import Optionalが必要。

from typing import Optional

# 引数がNoneであることも考慮した関数
def decorate_str(str_val: Optional[str]) -> str:
    if str_val is None:
        return "----- no value -----"
    return f"----- {str_val} -----"


print(decorate_str("test"))
print(decorate_str(None))

関数オブジェクト・コールバック – Callable型


 関数オブジェクトもType hintが可能です。

 Callable[[引数1の型, 引数2の型,…], 戻り値の型]というように表せます。

 from typing import Callableが必要。

from typing import Callable, List


# リストの隣合う2つの値を何かしら計算して返す
def calc_two_num(ls: List[int], func: Callable[[int, int], int]):
    result = []
    for i in range(len(ls) - 1):
        one_val, two_val = ls[i], ls[i + 1]
        calculated_val = func(one_val, two_val)
        result.append(calculated_val)
    return result


ls = [1, 2, 3, 4, 5]

print(calc_two_num(ls, lambda a, b: a + b))
print(calc_two_num(ls, lambda a, b: a * b))

GeneratorのTyping


 GeneratorもType hintが可能です。

 Generator[yieldで返す値の型, ?, ?]

 Generatorの2,3つ目の型は調べてもよく分からないです。yieldだけなら1つ目の型だけ指定すればいいです。

 from typing import Generatorが必要です。


import random
from typing import Generator


def random_int_generator() -> Generator[int, None, None]:
    for _ in range(3):
        yield random.randint(0, 10)


generator = random_int_generator()
for val in generator:
    print(val)

コメントを残す

メールアドレスが公開されることはありません。