複数ライブラリの排他選択的なインポート (Python 3)

2021-10-26

#Python3 モジュール

Python スクリプトで、互換性のある複数のライブラリ (パッケージ、モジュール) の何れかひとつを import したい場合があります。
例えば有名なライブラリの改良版が github で公開されている場合などです。
いくつかの異なるバージョンに互換性があり、実行環境にどのバージョンのライブラリが存在するか解らないとき、それらのうちで存在するものを選択する排他的な import を実現する方法はあるのでしょうか?

例外処理を活用する

Python には例外処理の仕組みがあるので、排他的な import は try … except 構文で綺麗に記述できます。
if 文を活用してライブラリの存在を確認するのだろうかと考えがちですが(一旦考えました)、例外 ImportError をキャッチするほうがずっと簡単です。

あるモジュール内のクラスと、そのモジュール自身を import する例で解説します。

try 内2行目の import foo が失敗するようなケースでは 1行目の from foo が必ず失敗する為、これで多重 import を防げます。
複数の独立したライブラリで同様の処理をする場合は、それぞれ個別に try … except を行ったほうが良いでしょう。

except 内の2行目では import bar as foo により bar モジュールを foo にリネームすることで、全く同じ名前でアクセスできるようにしています。

該当ライブラリがインストールされていない場合は、VSCode などの静的型チェック (Pylance, Pyright, mypy) でエラーが発生しますが、該当行にコメント # type: ignore を付けることで抑制できます。

なお、import 文では例外 ModuleNotFoundError が送出されることもありますが、この例外は ImportError のサブクラスなので except ImportError で捕捉できます。

参考

QooQ