-
-
Save hotchpotch/f0253edcc1d403ffb38740cf2e0ecc74 to your computer and use it in GitHub Desktop.
Python で型ヒントを書く
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
from typing import Any, Generic, Optional, TypeVar, Union, cast | |
from typing_extensions import TypedDict | |
s: str = "a" | |
# `:str` と書かなくても型推論される(この場合は自明だが…) | |
s_type_inference = "あ" | |
i: int = 1 | |
f: float = 3.14 | |
# 型が違うので型エラー | |
s + f | |
s_type_inference + f | |
l: list[str] = ["あ", "い"] | |
l.append(100) | |
d: dict[str, int] = {"a": 1} | |
d["b"] = 2 | |
d["c"] = "str" | |
# Union | |
str_or_int: str | int = 1 | |
# 同じ | |
str_or_int: Union[str, int] = 1 | |
str_or_int = "あ" | |
# Optional | |
str_or_none: str | None = None | |
# 同じ | |
str_or_none: Optional[str] = None | |
def safe_upper(word: str | None) -> str: | |
# None の可能性があるのでエラー | |
word.upper() | |
if word == None: | |
return "" | |
# ここではstr型と静的解析され、型エラーにならない | |
return word.upper() | |
# 特定の key, value の dict の定義 | |
class UserEntity(TypedDict): | |
user_id: int | |
name: str | |
# 型チェックもされるし補完もされる | |
user = UserEntity(user_id=1, name="foo") | |
user_type_error = UserEntity(user_id="1", name="bar") | |
# 実際はただの dict | |
print(user.__class__) # => dict | |
# dict syntaxでの代入もできる | |
user: UserEntity = {"user_id": 1, "name": "baz"} | |
user_type_error: UserEntity = {"user_id": "1", "name": "baz"} | |
# 型変数と制約 | |
T = TypeVar("T", str, int) | |
# クラスの場合は Generic を使う | |
class Adder(Generic[T]): | |
def __init__(self, value: T): | |
self.value = value | |
def add(self, n: T): | |
self.value = self.value + n | |
def get(self) -> T: | |
return self.value | |
# int | |
int_adder = Adder(3) | |
int_adder.add(2) | |
int_adder.get() | |
# str | |
str_adder = Adder("add") | |
str_adder.add("er") | |
str_adder.get() | |
str_adder.add(10) | |
# 関数 | |
def adder_func(a: T, b: T) -> T: | |
return a + b | |
int_res = adder_func(1, 2) | |
str_res = adder_func("foo", "bar") | |
def adder_func_戻り値が型推論されない(a: T, b: T): | |
""" | |
戻り値は T と推論してほしいが… | |
""" | |
return a + b | |
int_res_推論されない = adder_func_戻り値が型推論されない(1, 2) | |
#%% | |
# debug 時の型確認 | |
reveal_type(int_res) | |
reveal_type(str_res) | |
reveal_type(int_res_推論されない) | |
""" | |
# pyright コマンドを実行すると... | |
demo-1-presentation.py:105:13 - info: Type of "int_res" is "int" | |
demo-1-presentation.py:106:13 - info: Type of "str_res" is "str" | |
demo-1-presentation.py:107:13 - info: Type of "int_res_推論されない" is "str* | int*" | |
""" | |
#%% | |
# キャスト | |
i_any: Any = 1 | |
i = cast(int, i_any) | |
str_any: Any = "foobar" | |
i = cast(int, str_any) | |
# cast は あくまで型ヒントが変わるだけ | |
# 型ヒントではエラーにならないが、実行時エラー | |
i.bit_length() | |
#%% | |
# 型エラーの強制無視 | |
ten: int = "10" | |
ten: int = "10" # type: ignore | |
ten.bit_length() # もちろん実行時エラー |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment