Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Python 3.13で進化したtype predicateについてと、タグ付きユニオンを使っ...
Search
nsuz
December 22, 2024
Programming
330
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Python 3.13で進化したtype predicateについてと、タグ付きユニオンを使ったtype narrowingについて
Python札幌 シーズンX Vol.3 LT勉強会
発表資料
nsuz
December 22, 2024
More Decks by nsuz
See All by nsuz
「無ければ作る」Backlogに欲しい機能を自分で作った話
nsuz
0
1.6k
Other Decks in Programming
See All in Programming
Modding RubyKaigi for Myself
yui_knk
0
910
ふつうのFeature Flag実践入門
irof
7
3.7k
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
270
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
110
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
Contextとはなにか
chiroruxx
0
280
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
200
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
180
Webフレームワークの ベンチマークについて
yusukebe
0
160
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
520
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.9k
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
1.7k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
370
Building the Perfect Custom Keyboard
takai
2
790
The Invisible Side of Design
smashingmag
302
52k
Prompt Engineering for Job Search
mfonobong
0
340
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.3k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
The SEO Collaboration Effect
kristinabergwall1
1
480
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
Transcript
Python 3.13で進化したtype predicateについてと、タ グ付きユニオンを使ったtype narrowingについて 鈴木直柔 2024-12-23 Python札幌
自己紹介 鈴木直柔 (@nsuz) 株式会社 エクサウィザーズ ソフトウェアエンジニア
Python 3.13で進化したtype predicate
a: list[str | None] = ["foo", None, "bar", None, "baz"]
b = filter(lambda x: x is not None, a) c = map(lambda x: x.upper(), b)
None
type predicete function def is_not_none[T](x: T | None) -> TypeIs[T]:
return x is not None typing.TypeIs Python 3.13で追加された。TypeGuard(3.10~)の進化版。
None
TypeGuardから進化したポイント TypeGuardの課題
TypeGuardから進化したポイント TypeIs 型述語関数の返り値がTrueのとき、元の変数の型との交差型として推論されるよ うになった 型述語関数の返り値がFalseのときもnarrowingできるようになった
タグ付きユニオンを使ったtype narrowing
class Ok[T](TypedDict): type: Literal["ok"] value: T class Error(TypedDict): type: Literal["error"]
value: Exception type Result[T] = Ok[T] | Error def unwrap[T](result: Result[T]) -> T: if result["type"] == "ok": return result["value"] # result: Ok[T] else: raise result["value"] # result: Error
data: list[Result[int]] = [ {"type": "ok", "value": 42}, {"type": "error",
"value": ValueError("Something went wrong")}, ] for d in data: try: print(unwrap(d)) except Exception as e: print(f"Error!!!! {e}")
例えば・・・ APIレスポンスが、 成功時 { "result": 0, "data": ... } 失敗時
{ "result": 1, "error": ... } みたいなとき
from typing import Literal, TypedDict type Data = list[str] class
OkResponse(TypedDict): result: Literal[0] data: Data class ErrorResponse(TypedDict): result: Literal[1] error: str type Response = OkResponse | ErrorResponse def unwrap[T](res: Response) -> Data: if res["result"] == 0: return res["data"] else: raise Exception(res["error"]) data: list[Response] = [ {"result": 0, "data": ["foo", "bar", "baz"]}, {"result": 1, "error": "ERROR_CODE_123"}, ] for d in data: try: print(unwrap(d)) except Exception as e: print(f"Error!!!! {e}")
(ただ、Pythonの場合、内部でつくるデータについてはTypedDictでタグ付きユニオン をつくるよりも、dataclassなどでクラスにした方が、構造的パターンマッチングでス マートに扱えるかも・・?)
from dataclasses import dataclass @dataclass class Ok[T]: value: T @dataclass
class Error: value: Exception type Result[T] = Ok[T] | Error def unwrap[T](result: Result[T]) -> T: match result: case Ok(v): return v case Error(e): raise e
data: list[Result[int]] = [ Ok(42), Error(ValueError("Something went wrong")), ] for
d in data: try: print(unwrap(d)) except Exception as e: print(f"Error!!!! {e}")