今回は型で値を縛る方法をまとめた内容です。Python3.10から入った機能がいくつかあります。
いくつかPythonでtypingを使って型指定する記事について書いてるのでそちらも見ていただければと思います!
目次
取りうる値の範囲を指定できるLiteral型 – Python3.8から
Python3.8から入った機能。
Literal[取りうる値1, 取りうる値2]という感じで指定できる。Literal型の変数に指定していない値を入れようとした場合はエディタが怒ってくれる。
https://docs.python.org/ja/3/library/typing.html#typing.Literal
TypeScriptのunionみたいなイメージ。
https://typescriptbook.jp/reference/values-types-variables/union
from dataclasses import dataclass
from typing import Literal
@dataclass
class TaskInfo:
job_id: str
task_status: Literal["ok", "failed", "canceled"]
TaskInfo(task_status="ok", job_id="test_id")
TaskInfo(task_status="hoge", job_id="test_id") # これはエディタに怒られる
TypeGuardで型ガード – Python3.10から
Python3.10から入った新しい機能。
関数の戻り値の型にTypeGuard[型]を指定することで、引数が指定した型であることをエディタに認識させることができます。
TypeScriptの<arg> is <Type>みたいなイメージ。
https://typescript-jp.gitbook.io/deep-dive/type-system/typeguard#yznotype-guard
from typing import TypeGuard, TypedDict
class ErrorRes(TypedDict):
error_code: str
message: str
class SuccessRes(TypedDict):
status: int
message: str
def is_error_res(v: dict) -> TypeGuard[ErrorRes]:
return v.get("error_code") is not None
response = {
"error_code": "eee",
"message": "invalid parameters"
}
# if内はresponseはErrorRes型であることをエディタが認識する
if is_error_res(response):
print(response["error_code"]) # エディタが"error_code"キーを補完してくれる
print(response["status"]) # エディタに怒られる
TypeAliasで型に別名をつける – Python3.10から
Python3.10から入った機能。
<型名>: TypeAlias = <別名つけたい型>という形式で型に別名をつけられる。
https://www.python.jp/news/wnpython310/typealias.html
from typing import TypeAlias
JobId: TypeAlias = str
def cancel_job(job_id: JobId):
# キャンセル処理
pass
cancel_job("job_id")
cancel_job(12) # これだとエディタに怒られる
TypedDictで辞書dictに型をつける – Python3.8から
Python3.8から追加。
TypedDictを継承したクラスを指定するとdictでも型を間違えているとエディタが怒ってくれるようになる。
https://docs.python.org/ja/3/library/typing.html#typing.TypedDict
また、TypedDictを継承したクラスを継承したクラスもTypedDictとして使える。
from typing import TypedDict
class Person(TypedDict):
name: str
age: int
# Personを継承したStudentもTypedDictになる
class Student(Person):
grade: int
class Teacher(Person):
salary_by_month: int
d: Person = {
"name": 12, # 型が違うのでエディタに怒られる
"age": 12
}
del d["hoge"] # 存在しないキーなのでエディタに怒られる
s: Student = {
"grade": 123,
"name": "hoge",
"age": 12
}