【実践試験Tips.4】学習のポイント 型ヒント

こんにちは、Pythonエンジニア育成推進協会 顧問理事の寺田です。私は試験の問題策定とコミュニティ連携を行う立場です。

実践試験Tipsは、当協会のPython3エンジニア認定実践試験を受験される予定の方に向けて、何回かに分けてちょっとした情報をお伝えしていく目的で作成しています。

前回は主教材Chapter4 Pythonのクラスについて、これからクラスやオブジェクト指向を学ぶ方に向けたお話しました。

今回はChapter5 型ヒントについてお話したいと思います。

■学習のポイント:Chapter5 型ヒント

Python3エンジニア認定実践試験は、主教材「Python実践レシピ」(技術評論社)の中から出題されます。

出題範囲については以下のページをご確認ください。

Chapter5の型ヒントは 2節で構成されています。試験範囲となるのは5.1の型ヒントで、5.2の静的型チェックは範囲外です。

主教材が出版された4年前にはまだ型ヒントを書いている人が少なかったのですが、最近は型ヒントがないコードを見ると不安になる程度には、型ヒントが浸透しており、Pythonを書く際には型ヒントを書くことが標準的なものになってきていると認識しています。実際のプロジェクトにおいても、型ヒントを書くことを前提としていることも増えてきています。

私自身も、型ヒントがないコードのレビューは大変なのでしたくありませんし、型ヒントなしでコードを書く事もなくなりました。型ヒントがあると、間違いを見つけることが容易になるので、最初からバグの数を押さえられたり、AIが理解しやすいコードにすることができたりといったメリットもあります。

とはいえ、型ヒントを書くこと自体、ある種の手間ではありますので、動的型付け言語であるPythonにおいて、型ヒントは本当に書かなければいけないものなのかという議論は実際ありますし、書かない派もいます。なので、実際に実務上ではどうするかはチームで決めていくのが実情です。

ただ、先ほど挙げた通り、型ヒントの存在によるメリットはありますので、今後は慣れていく方がいいのではないかなと思います。ぜひ勉強して、書けるようになってもらえたらいいなと思っています。

■型ヒントを身に付けるポイント

型ヒントの基本として、変数に型をつける、または、変数に型をつけなくても、変数の型が明確なのであれば、自動的にその型を推測してくれるということがあります。そのため、オプション的なものかもしれませんが、変数に型を付けることのやり方を知っておく必要はあるかと思います。

次に、関数やメソッドの引数に型をつけられるようにすること、そして、戻り値に型をつけられるようにしていきます。これが上手くできるようになっていれば、型ヒントを8割ほど理解できていると考えていいのではないかと思います。

また、より高度な使い方としては、データクラスやPydanticを利用したり、複数の型を受け入れられるように型を工夫したり、リテラルを使ったりと様々な方法があります。また、別章で出てくる列挙型のEnum型をうまく活用するといった話がさらにその先に出てきます。

なので、まずは変数・引き数・戻り値に型をつけるといったことを、書籍をみながら身に付けることから始めましょう。

■型ヒントがつけにくいコードは設計に問題あり

型を付けるのが難しい関数も存在します。例えば、文字列・整数・浮動少数点のどれでもいいという引数や、リストが来るかもしれないし、文字列が来るかもしれないというような曖昧な引数です。また戻り値が文字列になったり、整数値になったりといったものもあり様々なパターンが存在します。

ただ、これは実装する側にとって、整理されていない状況とも考えられます。

この引数は必ず文字列だ、整数だ、というように型が明確にわかるような関数を作るべきです。これは戻り値に対しても同様です。

型ヒントに慣れれば、型をはっきりさせるものを作れるようになってくるはずです。

私自身、以前は複数の型をうまく受け取れるようにして、内部で if 文で分岐して処理を切り替えるという関数やメソッドをたくさん書いていたことがあります。今それを改めてみてみると、型が付けにくいことに気づき、関数の設計自体を変えようと考え、修正した結果、より分かりやすい関数になりました。また、複数のデータが来てしまうこと自体は仕方ないとした場合には、呼び出し側を分ける、別のものとして扱うといったことを行うことで、関数の分割や引数の役割の見直しがとても進み、より良いコードにすることができました。型ヒントを活用することで、より良いコードにする一歩を踏めるということで、型ヒントを重視しています。

■型ヒントのより発展的な利用方法

さらに発展的な話として、型をどんどん付けていくと、戻り値にも具体的な型を指定するようになります。

引数にも具体的な型を付けて受け渡すことは、当然よくあることです。

ただ、その際によくあるのが辞書(dict)でデータを渡すというケースでは、データ型がつけにくいことが起きます。もちろん dict と書けば型ヒント自体は付けられますが、どのようなキーが存在するのか、それぞれのキーに対応する値の型は何かといった情報までは分かりにくくなってしまうためです。

そうした場合に便利なのがTypedDictです。ただ、私はTypedDictより、データクラス化させてしまいます。辞書でインターフェイス(引数や戻り値)を定義していたところをなるべくデータクラス化してしまうということです。

データクラス化することで、コード量は少し増えてしまうものの、明確なオブジェクトが入っているということが分かりやすくなります。その結果、汎用性は低いものの、安全性の高い、明確な関数または明確な実装にすることができます。

このような型ヒントからデータクラスの必要性が出てきて、データクラスもうまく使いこなせるようになると、より分かりやすく、より堅牢な、読みやすいコードになります。

まずは型をつけることから始めてみてください。最初の内はたくさんのエラーが出て大変な思いをするかもしれませんが、なんとか乗り越えてほしいなと考えています。

■型ヒントの活用シーン

型ヒントの活用例としては、前回説明したデータクラスを書く際に、データの型を指定することができますので、そのデータが文字列なのか、整数なのかというのをあらかじめ宣言することができます。

この辺は型ヒントとの関連性の深い部分になりますし、昨今流行ってきているPydanticというデータ検証用のライブラリーにおいて、この型ヒントを非常にうまく活用することで、コーディングしやすく、かつ読みやすくコードを書くことができます。また、データの検証を明確に行える仕組みにできます。

■おまけ 5.2 静的型チェック mypy

5.2は試験範囲外ですが、簡単にお話をしておきます。

型ヒントを書いたとしても、Pythonは実行においてデータ型の型ヒントを使いませんので、静的にチェックをする、またはVS CodeなどのIDEの支援を受ける時以外には便利なことというのはありません。実際に型ヒントの静的型チェックを行う場合には、書籍で紹介しているmypyなどのツールを使って、書籍のやり方に則って実行してみてください。型エラーが出たら直せるというようになって欲しいと思います。

そうしていくことで型ヒントによって得られるメリットを感じ取れるようになるかと思います。

PAGE TOP