Python の型付け:コードの読みやすさを向上させる

PythonBeginner
オンラインで実践に進む

はじめに

このチュートリアルでは、Python のtypingモジュールを使ってコードに型ヒントを追加する方法を学びます。型ヒントは、関数の期待される入力と出力の型を明示的に示すことで、コードをより読みやすく保守しやすくするのに役立ちます。

基本型

型ヒントは Python 3.5 で導入された機能で、Python 3.5.2 では型注釈の標準セットを提供するためにtypingモジュールが追加されました。型ヒントを使用し始めるには、typingモジュールから関連する型をインポートします。

from typing import List, Tuple, Dict

基本型の型ヒントは簡単です。型自体をヒントとして使用します。

ターミナルで次のコマンドを入力して Python シェルを開きます。

python3
  1. int型の変数を定義し、値を割り当ててから表示します。
age: int = 25
print(age) #出力:25
  1. float型の変数を定義し、値を割り当ててから表示します。
temperature: float = 98.6
print(temperature) #出力:98.6
  1. bool型の変数を定義し、値を割り当ててから表示します。
is_raining: bool = True
print(is_raining) #出力:True
  1. str型の変数を定義し、値を割り当ててから表示します。
def greet(name: str) -> str:
    return f"Hello, {name}!"

print(greet("Alice")) #出力:Hello, Alice!
  1. int型の 2 つの引数を受け取り、それらを掛け合わせてint型の結果を返す関数を定義します。
def multiply(x: int, y: int) -> int:
    return x * y

result = multiply(5, 10)
print(result) #出力:50

コンテナとジェネリック

コンテナ型(リスト、辞書、セットなど)の型ヒントは、ジェネリックを使ってより詳細にすることができます。

ヒント:シリアルナンバー1 - 3 の実験は python シェルで実装でき、シリアルナンバー4 の実験は WebIDE で実装されます。

  1. List[int]型の変数を定義し、いくつかの値を割り当ててから表示します。
from typing import List
numbers: List[int] = [1, 2, 3, 4, 5]
print(numbers) #出力:[1, 2, 3, 4, 5]
  1. Dict[str, int]型の変数を定義し、いくつかのキーと値のペアを割り当ててから表示します。
from typing import Dict
ages: Dict[str, int] = {"Alice": 25, "Bob": 30, "Charlie": 35}
print(ages) #出力:{'Alice': 25, 'Bob': 30, 'Charlie': 35}
  1. Tuple[str, int, float]型の変数を定義し、いくつかの値を割り当ててから表示します。
from typing import Tuple
person: Tuple[str, int, float] = ("Alice", 25, 5.7)
print(person) #出力:('Alice', 25, 5.7)
  1. 整数のリストを引数として受け取り、新しい整数のセットとして結果を返す関数を定義します。
    WebIDE でlist_to_set.pyというプロジェクトを作成し、次の内容を入力します。
from typing import List, Set

def get_unique_elements(elements: List[int]) -> Set[int]:
    return set(elements)

numbers = [1, 2, 2, 3, 4, 4, 4, 5]
unique_numbers = get_unique_elements(numbers)
print(unique_numbers)  #出力:{1, 2, 3, 4, 5}

次のコマンドを使ってスクリプトを実行します。

python list_to_set.py

ユーザ定義型

カスタム型やクラスを型ヒントとしても使用できます。

ヒント:この実験は WebIDE で実装されます。

  1. name (str)age (int) の型付き属性と、人物の名前と年齢を要約する文字列を返す get_summary メソッドを持つ Person クラスを定義します。
    WebIDE で str_and_int_to_str.py というプロジェクトを作成し、次の内容を入力します。
class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age
    def get_summary(self) -> str:
        return f"{self.name} is {self.age} years old."

person1 = Person("Alice", 25)
print(person1.get_summary()) #出力:Alice is 25 years old.

次のコマンドを使ってスクリプトを実行します。

python str_and_int_to_str.py
  1. xy の型付き属性を持ち、両方とも float 型で、2 点間の距離を返す distance メソッドを持つ Point クラスを定義します。
    WebIDE で other_to_float.py というプロジェクトを作成し、次の内容を入力します。
import math

class Point:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y
    def distance(self, other: "Point") -> float:
        return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)

point1 = Point(0, 0)
point2 = Point(3, 4)
print(point1.distance(point2)) #出力:5.0

次のコマンドを使ってスクリプトを実行します。

python other_to_float.py

型エイリアス

型エイリアスは、特に複雑な型に対して、より読みやすい型ヒントを作成することができます。
WebIDE で type_aliases.py というプロジェクトを作成し、次の内容を入力します。

from typing import List, Tuple

Coordinate = Tuple[float, float]
Path = List[Coordinate]

def get_distance(coord1: Coordinate, coord2: Coordinate) -> float:
    return ((coord1[0] - coord2[0])**2 + (coord1[1] - coord2[1])**2)**0.5

start = (0, 0)
end = (3, 4)
print(get_distance(start, end))  #出力:5.0

次のコマンドを使ってスクリプトを実行します。

python type_aliases.py

オプショナルと None

値が特定の型のいずれかまたは None のいずれかである場合、Optional 型を使用できます。

  1. オプショナルな int 引数を受け取り、それが None でない場合に 2 倍にして返し、入力が None の場合は int または None として結果を返す関数を定義します。
    WebIDE で option_and_none_1.py というプロジェクトを作成し、次の内容を入力します。
from typing import Optional

def double_or_none(number: Optional[int]) -> Optional[int]:
    if number is not None:
        return number * 2
    else:
        return None

result1 = double_or_none(5)
result2 = double_or_none(None)
print(result1, result2) #出力:10 None

次のコマンドを使ってスクリプトを実行します。

python option_and_none_1.py
  1. 型付き属性 address を持ち、有効な住所文字列を持つか None のいずれかである Person クラスを定義します。
    WebIDE で option_and_none_2.py というプロジェクトを作成し、次の内容を入力します。
from typing import Optional

class Person:
    def __init__(self, name: str, age: int, address: Optional[str]):
        self.name = name
        self.age = age
        self.address = address

person1 = Person("Alice", 25, "123 Main St")
person2 = Person("Bob", 30, None)
print(person1.name, person1.age, person1.address) #出力:Alice 25 123 Main St
print(person2.name, person2.age, person2.address) #出力:Bob 30 None

次のコマンドを使ってスクリプトを実行します。

python option_and_none_2.py

コール可能オブジェクト

Callable 型は、関数またはメソッドの型を指定するために使用されます。
WebIDE で callable.py というプロジェクトを作成し、次の内容を入力します。

from typing import Callable

def apply_function(value: int, func: Callable[[int], int]) -> int:
    return func(value)

def double(x: int) -> int:
    return x * 2

print(apply_function(5, double))  #出力:10

次のコマンドを使ってスクリプトを実行します。

python callable.py

TypedDict

TypedDict を使用すると、特定のキーと値の型を持つカスタム辞書を作成できます。

ヒント:TypedDict は Python 3.8 で導入されました。したがって、使用するには Python 3.8 以降が必要です。

以下は例です。
WebIDE で typeddict.py というプロジェクトを作成し、次の内容を入力します。

from typing import TypedDict

class PersonInfo(TypedDict):
    name: str
    age: int

def greet(person: PersonInfo) -> str:
    return f"Hello, {person['name']}! You are {person['age']} years old."

alice_info: PersonInfo = {"name": "Alice", "age": 30}
print(greet(alice_info))  #出力:Hello, Alice! You are 30 years old.

次のコマンドを使ってスクリプトを実行します。

python typeddict.py

Newtype

NewType は、Python の typing モジュールからの型ヒントであり、既存の型をラップするだけの新しい型を作成することができます。これは、変数や関数の引数により多くの意味を追加するために役立ちます。

以下は例です。
WebIDE で newtype.py というプロジェクトを作成し、次の内容を入力します。
その後、次の Python スクリプトを実行します。

from typing import NewType

UserId = NewType("UserId", int)
OrderId = NewType("OrderId", int)

def get_order(order_id: OrderId) -> str:
    return f"Order with ID: {order_id}"

order_id = OrderId(123)
user_id = UserId(123)

print(get_order(order_id))  #出力:Order with ID: 123

次のコマンドを使ってスクリプトを実行します。

python newtype.py

静的型チェッキング

Python では、型ヒントと mypy のような静的型チェッカーを使って静的型チェックを行うことができます。型ヒントは、変数、関数の引数、および戻り値の期待される型を示します。以下は例です。

まず、mypy をインストールします。

pip install mypy

以下は例です。
WebIDE で mypy.py というプロジェクトを作成し、次の内容を入力します。

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

result = add_numbers(2, 3)
print(result)

その後、スクリプトに対して mypy を実行します。

mypy mypy.py

これにより、コードに見つかった型の不一致に関するフィードバックが得られます。

まとめ

以上です!これで、Python の typing モジュールを使ってコードに型ヒントを追加する方法を知ることができました。型ヒントは、コードの読みやすさと保守性を大幅に向上させ、より大きなコードベースで作業したり、他の人と協力したりするのを容易にします。