Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
2021年の型駆動開発 / type-driven-design-in-2021-python
Peacock
May 07, 2021
Programming
2
120
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
Getting Started with Statically Typed Programming in Python 3.10 / PyConUS2022
peacock0803sz
0
14
Getting Started with Statically Typed Programming in Python 3.10 / PyCon APAC 2021
peacock0803sz
0
50
Python3.10からはじめる型ヒント / stapy74
peacock0803sz
0
470
Announcement from PyCon JP 2021
peacock0803sz
0
52
Getting Started with Statically Typed Programming in Python 3.10
peacock0803sz
0
940
Pythonではじめる今風な型プログラミング / osc21do
peacock0803sz
1
130
Other Decks in Programming
See All in Programming
Amebaブログの会員画面システム刷新の道程
ryotasugawara
1
210
量子コンピュータ時代のプログラミングセミナー / 20230119_Amplify_seminar _shift_optimization
fixstars
0
150
SHOWROOMの分析目的を意識した伝え方・コミュニケーション
hatapu
0
230
Most Valuable Bug(?) ~インシデント未遂から得た学び~
tatsumiakahori
0
140
Swift Expression Macros: a practical introduction
kishikawakatsumi
2
700
(新米)エンジニアリングマネージャーのしごと #RSGT2023
murabayashi
9
5.4k
Use KMM to call the API of the National Tax Agency
akkeylab
0
290
23年のJavaトレンドは?Quarkusで理解するコンテナネイティブJava
tatsuya1bm
1
110
An Advanced Introduction to R
nicetak
0
1.6k
Qiita Night PHP 2023
fuwasegu
0
830
Micro Frontends with Module Federation @MicroFrontend Summit 2023
manfredsteyer
PRO
0
430
Zynq MP SoC で楽しむエッジコンピューティング ~RTLプログラミングのススメ~
ryuz88
0
230
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
13
1.1k
Making Projects Easy
brettharned
102
4.8k
Mobile First: as difficult as doing things right
swwweet
213
7.8k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
32
6.7k
What's in a price? How to price your products and services
michaelherold
233
9.7k
Infographics Made Easy
chrislema
235
17k
Support Driven Design
roundedbygravity
88
8.9k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
63k
Adopting Sorbet at Scale
ufuk
65
7.8k
Fontdeck: Realign not Redesign
paulrobertlloyd
74
4.3k
Clear Off the Table
cherdarchuk
79
290k
Making the Leap to Tech Lead
cromwellryan
116
7.6k
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