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
300
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
270
Comparison of Packaging Tools in 2023 (PyCon TW 2023)
peacock0803sz
0
47
Getting Started with Statically Typed Programming in Python 3.10 / PyConUS2022
peacock0803sz
0
75
Getting Started with Statically Typed Programming in Python 3.10 / PyCon APAC 2021
peacock0803sz
0
140
Python3.10からはじめる型ヒント / stapy74
peacock0803sz
0
1.1k
Announcement from PyCon JP 2021
peacock0803sz
0
170
Getting Started with Statically Typed Programming in Python 3.10
peacock0803sz
0
1.4k
Pythonではじめる今風な型プログラミング / osc21do
peacock0803sz
1
290
Other Decks in Programming
See All in Programming
ある日突然あなたが管理しているサーバーにDDoSが来たらどうなるでしょう?知ってるようで何も知らなかったDDoS攻撃と対策 #phpcon.2024
akase244
2
7.7k
HTML/CSS超絶浅い説明
yuki0329
0
190
バグを見つけた?それAppleに直してもらおう!
uetyo
0
220
ErdMap: Thinking about a map for Rails applications
makicamel
1
540
return文におけるstd::moveについて
onihusube
1
1.4k
オニオンアーキテクチャを使って、 Unityと.NETでコードを共有する
soi013
0
370
Androidアプリのモジュール分割における:x:commonを考える
okuzawats
1
270
DMMオンラインサロンアプリのSwift化
hayatan
0
160
月刊 競技プログラミングをお仕事に役立てるには
terryu16
1
1.2k
令和7年版 あなたが使ってよいフロントエンド機能とは
mugi_uno
10
4.9k
Асинхронность неизбежна: как мы проектировали сервис уведомлений
lamodatech
0
1.3k
どうして手を動かすよりもチーム内のコードレビューを優先するべきなのか
okashoi
3
860
Featured
See All Featured
Building an army of robots
kneath
302
45k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.5k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3.1k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
What's in a price? How to price your products and services
michaelherold
244
12k
Code Reviewing Like a Champion
maltzj
521
39k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
230
52k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Gamification - CAS2011
davidbonilla
80
5.1k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.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