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
2021年の型駆動開発 / type-driven-design-in-2021-python
Search
Peacock
May 07, 2021
Programming
2
250
2021年の型駆動開発 / type-driven-design-in-2021-python
2021/05/07 CMScom techtalk
Peacock
May 07, 2021
Tweet
Share
More Decks by Peacock
See All by Peacock
Comparison of Packaging Tools in 2023 (PyCon APAC 2023)
peacock0803sz
0
49
Comparison of Packaging Tools in 2023 (PyCon TW 2023)
peacock0803sz
0
30
Getting Started with Statically Typed Programming in Python 3.10 / PyConUS2022
peacock0803sz
0
67
Getting Started with Statically Typed Programming in Python 3.10 / PyCon APAC 2021
peacock0803sz
0
120
Python3.10からはじめる型ヒント / stapy74
peacock0803sz
0
780
Announcement from PyCon JP 2021
peacock0803sz
0
140
Getting Started with Statically Typed Programming in Python 3.10
peacock0803sz
0
1.4k
Pythonではじめる今風な型プログラミング / osc21do
peacock0803sz
1
260
Other Decks in Programming
See All in Programming
Scala におけるコンパイラエラーとの付き合い方
chencmd
2
410
ブラウザ互換の重要性 - あらゆるユーザーに価値を届けるために必要なこと
yamanoku
0
110
Lessons by WebAssembly app in production on CDN Edge Computing Service
tetsuharuohzeki
0
190
Ruby Parser progress report 2024
yui_knk
2
220
LangGraphでのHuman-in-the-Loopの実装
os1ma
3
1k
[DroidKaigi 2024] Android ViewからJetpack Composeへ 〜Jetpack Compose移行のすゝめ〜 / From Android View to Jetpack Compose: A Guide to Migration
syarihu
1
330
長期運用プロダクトの開発速度を維持し続けるためのリファクタリング実践例
wataruss
8
2.7k
GraphQLの魅力を引き出すAndroidクライアント実装
morux2
3
390
Prompt Cachingは本当に効果的なのか検証してみた.pdf
ttnyt8701
0
530
Rechartsで楽にゴリゴリにカスタマイズする!
10tera
1
160
RAGの回答精度評価用のQAデータセットを生成AIに作らせた話
kurahara
0
240
Scala アプリケーションのビルドを改善してデプロイ時間を 1/4 にした話 | How I improved the build of my Scala application and reduced deployment time by 4x
nomadblacky
1
160
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
In The Pink: A Labor of Love
frogandcode
139
22k
Product Roadmaps are Hard
iamctodd
PRO
48
10k
Designing Experiences People Love
moore
138
23k
The Straight Up "How To Draw Better" Workshop
denniskardys
230
130k
Teambox: Starting and Learning
jrom
131
8.7k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
36
1.7k
What's new in Ruby 2.0
geeforr
340
31k
Intergalactic Javascript Robots from Outer Space
tanoku
268
26k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
8.9k
Done Done
chrislema
180
16k
Transcript
2021 年の型駆動設計( 開発) CMScom Techtalk 2021/05/07
1. Type hint ざっくり復習 i. 関数定義のところから書くのがおすすめ 2. Python3.10 style な
type hinting i. 3.9, 3.10 の Type hint 系新機能を紹介 ii. Pattern Matching, str.removeprefix() とか他の機能については話さない 3. 型を意識して設計するということ Table of Contents 2 / 21
書いている → 少し⾶ばして後半に議論したい 書いていない → 前に話したことを少し説明します はじめに: Type hint 書いてますか?
3 / 21
2020/09/11 TechTalk で話したこと
5 / 21
6 / 21
7 / 21
3.10 Style な type hinting
次ページから1 つずつ⾒ていきます 3.8 → 3.9 ⼩⽂字始まりの標準コレクション型ヒント 3.9 → 3.10 Union
型演算⼦ | 引数仕様変数 ( 原題: Parameter Specification Variables) 明⽰的な型エイリアス 3.8 から何が変わったか概要 9 / 21
3.9 からの新機能 list, dict, Iterable, etc... PEP 585 のページで列挙されている list[str]
のように書く 前に話した from typing import List は書かなくていい リリースから5 年後( つまり2025 年) には⾮推奨になる collections 系の⾊々はライブラリ開発とかでもなければ普段使わなさそう re.Match, re.Pattern につくのは便利そう PEP 585: ⼩⽂字始まりの標準コレクション型ヒント 10 / 21
3.10 の新機能 Union の糖⾐構⽂として | が使えるようになった str | int ==
Union[str, int] TypeScript とか Haskell がこの記法を使っている より直感的で記述量が減るのでうれしい def square(number: int | float) -> int | float: return number ** 2 # isinstance() でも使える >>> isinstance(1, int | str) True PEP 604: Union 型演算⼦ | 11 / 21
3.10 の新機能 Callable[T, R] の T に今までは tuple, Generics を渡せなかった
str, int などの型 or elipsis ( ... ) なら⼤丈夫だった 以下の例のように書けるようになる デコレーターを書くときに便利そう( まだ使ったことない) P = ParamSpec("P") def validation: (f: Callable[P, str]) -> Callable[P, bool]: def inner(s: str) -> bool: retrun s.isascii() PEP 612: 引数仕様変数 ( 原題: Parameter Specification Variables) 12 / 21
3.10 の新機能 エイリアス型がエイリアスであるとより明⽰的になる # Before 3.10 JsonLikeDict = dict[Union[str, int],
Any] # After 3.10 JsonLikeDict: TypeAlias = dict[Union[str, int], Any] # Union を新しい記法にしたバージョン JsonLikeDict: TypeAlias = dict[str | int, Any] PEP 613: 明⽰的な型エイリアス 13 / 21
これらを Python3.7, 3.8 のコードで使うには from __future__ import annotations を書く __future__
: 今後実装予定のモジュール 3.6 には⾮対応: PEP 563 dunder module (?) なので⼀番最初に書く from __future__ import annotations from datetime import datetime from __future__ import annotations を書く 14 / 21
型を意識して設計する 「型駆動開発」を1 年くらい実践して得た Best practices
Optional は便利だけどコードが肥⼤化していく原因 def get_content() -> str | None: r =
request.get("https://example.com") if r.status_code != 200: # ここがガード(早期リターン) logging.warning("HTTP response is %d!", r.status_code) return None return r.text ↑の関数を使うときにまたガードを書いて None を返すかもしれない 結果、先のメソッドまでガードを書く必要があり可読性が落ちる Optional をなるべく使わない 16 / 21
この場合なら raise RuntimeError なりしてしまったほうがすっきりする Python は例外を発⽣させるコストが( ⽐較的) 低いのでパフォーマンスも ⼤丈夫なはず Python
に null 安全なメソッドがないのも⼀因だけど、あるとそれはそれで 乱⽤してしまう Null 安全とは: Null(None) を渡しても例外が発⽣しないメソッド Plone の View とかがこれで書けるかはわからないけど、内部に使っている 関数レベルでならできそう 17 / 21
Language Server(LS): エディタで補完機能などをサポートしてくれる機能 Pylance(VS Code extension), Jedi が有名 裏でプロセスが⾛っていて、エディタと通信して動く ⾃明な型は書かない、Language
Server の推論がやってくれる 変数に型ヒントつける基準は推論が効かなくなる( Any 判定される) とき 必要があればガードをする。そうすれば取りうる型の範囲が狭まる 次ページにサンプルがあります Language Server の⼒を借りる 18 / 21
i: int = random.randint(1, 5) # `: int` は書かない r
= request.get("http://example.com/api.json") d: dict = json.loads(r.text) if r.status_code == 200 else {} if d == {}: # エラー処理 logger.error("Response is empty!") raise RuntimeError pass # ここで `d` は空dictの可能性がなくなっている 19 / 21
関数定義のところから Type hint 書いていきましょう Python3.10 style な type hinting ⼩⽂字始まりの標準コレクション型ヒント
(3.9) Union 型演算⼦ | (3.10) 引数仕様変数 (3.10) 明⽰的な型エイリアス (3.10) 型を意識して設計すると全体の⾒通しが良くなるのでおすすめ まとめ 20 / 21
Thank you for listening! This slide is made by marp