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
360
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
300
Comparison of Packaging Tools in 2023 (PyCon TW 2023)
peacock0803sz
0
75
Getting Started with Statically Typed Programming in Python 3.10 / PyConUS2022
peacock0803sz
0
83
Getting Started with Statically Typed Programming in Python 3.10 / PyCon APAC 2021
peacock0803sz
0
160
Python3.10からはじめる型ヒント / stapy74
peacock0803sz
0
1.5k
Announcement from PyCon JP 2021
peacock0803sz
0
200
Getting Started with Statically Typed Programming in Python 3.10
peacock0803sz
0
1.5k
Pythonではじめる今風な型プログラミング / osc21do
peacock0803sz
1
310
Other Decks in Programming
See All in Programming
第9回 情シス転職ミートアップ 株式会社IVRy(アイブリー)の紹介
ivry_presentationmaterials
1
260
#QiitaBash MCPのセキュリティ
ryosukedtomita
0
900
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
220
CursorはMCPを使った方が良いぞ
taigakono
1
220
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
260
AIエージェントはこう育てる - GitHub Copilot Agentとチームの共進化サイクル
koboriakira
0
490
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
630
AI時代のソフトウェア開発を考える(2025/07版) / Agentic Software Engineering Findy 2025-07 Edition
twada
PRO
50
13k
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
1.9k
Porting a visionOS App to Android XR
akkeylab
0
230
Rubyでやりたい駆動開発 / Ruby driven development
chobishiba
1
590
童醫院敏捷轉型的實踐經驗
cclai999
0
210
Featured
See All Featured
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
How GitHub (no longer) Works
holman
314
140k
Raft: Consensus for Rubyists
vanstee
140
7k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
A designer walks into a library…
pauljervisheath
207
24k
Building Applications with DynamoDB
mza
95
6.5k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Optimising Largest Contentful Paint
csswizardry
37
3.3k
Scaling GitHub
holman
459
140k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.8k
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