Pythonで「str | None」と書いたらエラーになった話〜AI時代の型ヒント入門〜
みなさん、こんにちは!AIとPythonが大好きな技術ブロガーのりりあです。
今日は「TypeScriptの感覚でPythonを書いたら、まさかの実行時エラーで爆死した」という、初心者あるあるなお話をお届けします。
AIやChatGPT、LLM(大規模言語モデル)を触っていると、Pythonのコードを読む機会がぐっと増えましたよね。でも、他言語から来た人が最初につまずくポイントが、この「型ヒント」なんです。
まず再現コードを見てみよう
あなたがTypeScriptに慣れているとして、こんなコードを書いたとします。
- TS版:
function findUser(id: number): string | null - Python版:
def find_user(user_id: int) -> str | None:
見た目はそっくり!なのに、Python 3.9以前でこれを実行すると……
TypeError: unsupported operand type(s) for |: ‘type’ and ‘type’
「えっ、型ヒント書いただけなのに、なんで実行時に怒られるの??」ってなりますよね。これ、PythonとTypeScriptの決定的な違いが隠れているんです。
違い①:Pythonの型ヒントは「実行時に評価される」
ここが最大の落とし穴!
- TypeScriptの型:コンパイル時に消える。実行時には1文字も残らない。だから型をいくら書いても動作は壊れない。
- Pythonの型ヒント:ただの「式」として実行時に評価される。
つまりPythonでは、str | Noneという式を「実際に計算しようとする」わけです。ところが、Python 3.9以前のtypeオブジェクト同士は、|演算子で繋げられません。だから「そんな計算できないよ!」とTypeErrorになるんですね。
例えるなら、TSは「設計図にメモを書くだけ」、Pythonは「設計図のメモをその場で実際に組み立てようとする」イメージです。
解決策:from __future__ import annotations
Python 3.10以降ならstr | Noneは正式サポートされています。でも、まだ3.9以前の環境(古いサーバーやライブラリ)を使っている人も多いですよね。
そんなときの魔法の呪文がこれ!
from __future__ import annotationsをファイルの先頭に書く- あるいは
Optional[str]を使う(typingモジュールからimport)
この__future__インポートをすると、型ヒントが文字列として遅延評価されるようになります。つまり「その場で組み立てず、後で読むだけ」になるので、エラーが起きないんですね。
AI・機械学習のコードを読むときにも役立つ豆知識
実はこの知識、データサイエンスやAI系ライブラリのコードを読むときにめちゃくちゃ役立ちます。ChatGPTやLLM関連のOSSは、型ヒントをガンガン使っているからです。
- 型ヒントは「実行時にも動く式」だと覚えておく
- バージョン差異で動かないときは
__future__を疑う - 新しい記法ほど「Pythonのバージョンの壁」にぶつかりやすい
ちなみに、mypyなどの型チェッカーは静的に解析してくれるので、実行前にミスを教えてくれます。AIコーディング時代こそ、こうした型の基礎があなたを守ってくれますよ!
まとめ:今日から使える3つのポイント
- Pythonの型ヒントは実行時に評価される(TSとはここが違う!)
- 3.9以前で
str | Noneを使いたいならfrom __future__ import annotations - 古い環境では
Optional[str]が安全な選択肢
夢は叶わなかったけど、AIがいるからまだ諦めない!
今日も一歩ずつ、PythonとAIの世界を一緒に楽しんでいきましょうねっ。推しはAI、担当はあたし!