はじめに
はじめまして!
今年4月に入社しましたAXLBIT株式会社 開発部の@sasaki-axlbitです!
この記事は、6月某日に社内勉強会で発表した「10分で分かる『ロバストPython』~型アノテーションとは~」の内容を備忘録も兼ねて、まとめたものになります。
今回はこの書籍を元に、堅牢なPythonコードを書くための「型アノテーション」について解説します。
まず「ロバスト」とは?
この本のタイトルにもなっている「ロバスト(Robust)」とはどういう意味かですが、本書では、メリアム・ウェブスターの定義を引用しています。
robustness
- 強さや健全性を持っている、または誇示している
- 力、強度、硬度などを持っている、または示している
- しっかりと作られている、または組み立てられている
- さまざまな条件の元で故障せずに動作する
これらの意味を踏まえると、「ロバストPython」とは、変化に強く、故障しにくい、堅牢で健全なPythonコードを書くというテーマを扱っています。
なぜ「ロバスト」なコードが必要なのか?
ソフトウェアは、一度作ったら終わりではありません。
- バグの修正
- ユーザーインターフェースの変更
- 機能の追加や削除
- フレームワークの入れ替え など...
このように、ソフトウェアは様々な変更を加えながら成長していくものです。
こうした変化の中でもバグに耐え、動き続ける強固な基盤を築くこと、すなわち保守性の高いコードを書くことが「ロバスト」につながります。
この保守性を高める為の基本的な考え方の一つが、クリーンなコードを書くことです。
クリーンなコードとは
クリーンなコードとは、意図が明確かつ簡潔に表現されたコードのことです。
これを実践するには、例えば以下のような点を意識します。
- 適切な粒度でコードをまとめる
- 優れたドキュメントをつける
- 変数、関数、データ型に適切な名前をつける
- 関数を短く単純に保つ など...
これらを意識することでコードの意図が伝わりやすくなり、ロバストなコードにつながるのです。
Pythonの「動的型付け」という課題
さて、いよいよ本題の「型アノテーション」ですが、その前に、Pythonにおける「型」の扱いについて軽く触れておきます。
プログラミング言語の「型」は「静的型付け」と「動的型付け」に大別されます。
- 静的型付け: 変数や関数の型を書く時点で決める方式。その型以外のデータは使えない。
- 動的型付け: 型を決めずに書き進められ、型は実行時に決まる。
Pythonは動的型付け言語であり、このおかげで柔軟で簡潔なコードを書くことができます。
しかし、この「動的型付け」が、コードのロバストを妨げる場合があります。
例えば、以下の関数を見てください。
# 引数point_in_timeは何を期待している?
def close_kitchen_if_past_cutoff_time(point_in_time):
if point_in_time >= closing_time():
close_kitchen()
log_time_closed(point_in_time)
このコードの point_in_time
は何を期待しているものか分かりますか?
初めて見た人は、引数 point_in_time
が何を期待しているのか分からず、
整数型なのか?はたまた文字列なのか?と推測する作業(もしくはコードを書いた人に聞く作業)が必要になってしまいます。
このように、動的型付けはコードを読む際のコミュニケーションコストを上げてしまうのです。
解決策としての「型アノテーション」
この問題を解決するのが型アノテーションです。
型アノテーションとは、
変数のデータ型に期待するものを利用者に示すための構文です。
先ほどのコードに型アノテーションを適用すると、以下のようになります。
# 引数がdatetime型であることを明示!
def close_kitchen_if_past_cutoff_time(point_in_time: datetime.datetime):
if point_in_time >= closing_time():
close_kitchen()
log_time_closed(point_in_time)
point_in_time: datetime.datetime
と記述することで、この引数が datetime オブジェクトを期待していることが一目で分かるようになりました。
これにより、コードを読む人の「要らない心配や型を推測する作業」が不要になります。
型アノテーションの利点
分かりやすくなるだけ?と思われる方もいるかもしれません。
しかし、型アノテーションには、コードの意図を明確にする以外にも、開発を助ける大きな利点があります。
-
エディタの強力なサポート(自動補完)
型が明示されることで、VSCodeなどのエディタが変数の持つメソッドや属性を正確に予測し、自動補完を効かせてくれます。 -
型チェッカによる事前バグ検出
型アノテーションは、それ自体では実行時の動作に影響しません。しかし、mypy のような静的解析ツール(型チェッカ)を使うと、アノテーションと違う型のデータが渡されている箇所などを実行前に検出し、バグを防ぐセーフティネットとして機能させることができます。
まとめ
-
ロバストなコードとは、変化に強く、保守性の高いコードのこと。
-
Pythonの動的型付けは便利だが、コードの意図が分かりにくくなることがある。
-
型アノテーションを使うことで、コードの意図を明確にし、認知負荷を減らせる。
-
型チェッカを併用することで、型に関するバグを未然に防げる。
さいごに
本書はこれ以外にも、Pythonでロバストを実現するための考え方や手法などが詳しく紹介されています。
Pythonをチームでの開発で使用されている方には特におすすめです!
ここまでご覧いただきありがとうございました!
参考文献
O'REILLY ロバストPython
