Python 3.12のGenerics(ジェネリクス)の書き方がクリーンになった記憶はまだ新しいです。
ですが、実際にPythonプロジェクトでGenericsを使っていないケースも多く見受けられます。「使わなくても実装できる」という前提はあるものの、Genericsはより汎用的かつ実用的なコードを書く際にとても便利です。
このコンテンツでは、「PythonのGenericsってなんぞや」という人向けにPythonのGenericsについて簡単に紹介します。
Genericsとは、汎用型(または総称型)と呼ばれる汎用的な型に対応できるクラスや関数を作れる機能のことを指します。TypeScriptやJava、最近ではRustで馴染みのある機能です。
わかりやすく一旦TypeScriptで書くと、以下のような形になります。
どちらの関数も同じく引数のval
を返すだけですが、型が違うことによって別々の関数として定義しなくてはいけません。これを汎用的な関数にしたいため、Genericsを利用して書き直します。
このように、Genericsを使うと関数実行時に型を定める書き方ができるようになります。
なぜGenericsを使うと嬉しいか、いくつかのポイントがあります。以下がGenericsを使うメリットとなります。
any
、Pythonでいうtyping.Any
の撲滅に貢献linterでコードチェックしているときに引っかかる問題へ役立ちます。
ただし、注意したほうが良いのは、正しい用法を理解した上で利用することです。
複数の型に対応できるということで、あやふやコード設計の上でGenericsを使い倒してしまうと、最終的に型安全ではないコードが量産されてしまいます。
それゆえ、Genericsは限定的な使い方をするのをおすすめします。
ここで本題となりますが、PythonによるGenerics構文を見ていきましょう。
まずは、Python 3.11以前の書き方を紹介します。
見て分かる通り、冗長な書き方をするしか方法がありませんでした。
これがPython 3.12で以下のように書けるようになりました。
このように、現行最新バージョンのPythonでは、TypeScriptなどに近い書き方が可能です。
Pythonは静的型付け言語ではないため、真のGenericsと呼べるかは微妙なラインです。しかしながら、タイプヒンティングをより取り入れたコーディングのために、新たな記法が生まれてくれたおかげでPythonらしさが保たれたように感じます。
Pythonコーディングに慣れていると、とっつきにくいと感じやすいですが、便利な機能なのでぜひ導入してみてください。