オプションのモジュールをインポートしようとするときにImportErrorをキャッチしても安全ですか?


10

通常、このパターンは、作業中のすべてのPythonプロジェクトで少なくとも1回は見られます。たとえば、Djangoプロジェクトでは、これは多くの場合、基本設定ファイルの最後に追加されます。

try:
  from .local_settings import *
except ImportError:
  pass

また:

try:
  import simplejson as json
except ImportError:
  import json

これはいつも私を少しでも悩ませてきました。モジュールが正常にインポートされた後、ImportErrorそれ自体がトリガーされるとどうなりますか?たとえば、最初の例では、local_settingsモジュールは存在しますが、local_settings存在しないモジュールをインポートしようとします。

これはオプションのモジュールをインポートする最も安全な方法ですか、この機能を実現するためのより良い方法はありますか?それはコンテキスト/使用法に依存しますか(そうであれば、このアプローチをいつ使用するかを決定するガイドラインは何ですか?)

回答:


10

一般的に、インポートするオプションの依存関係はそれ自体で機能することが想定されています。欠落しているオプションの依存関係をインポートしようとすることと、必要な推移的依存関係が欠落しているためにインポートできないこととの違いはほとんどありません。

言い換えると、プログラムがsimplejsonインストールされていないため、またはの依存関係がインストールされていないために、プログラムが使用できないことに注意する必要があるのはなぜsimplejsonですか?どちらの方法でも使用できませんsimplejson

オプションの依存関係の場合、推移的な依存関係を含め、依存関係が正しくインストールされていることを確認するのはパッケージインストーラーの役割です。

のようなものについてlocal_settingsは、実際に、他動詞ImportErrorがマスクされる(小さな)リスクがあります。キャッチされたImportError例外をレベルDEBUGまたは同様のレベルでいつでもログに記録して、例外の原因となった可能性のあるものを簡単に確認できます。

try:
    from .local_settings import *
except ImportError:
    log.debug('local_settings failed to import', exc_info=True)

loggingパッケージには、設定後の検査のためにログに例外情報が含まれますexc_infotrueにします。

別のオプションは、warningsモジュールで警告を発行することです。標準ライブラリには、このためのImportWarningクラスがあります。

import warnings

try:
    from .local_settings import *
except ImportError:
    warnings.warn('local_settings failed to import', ImportWarning)

私はそれと一緒に、またはそれをログに記録するのではなく、公式ドキュメントで言及されているImportWarningを使用することをお勧めします。
Eray Erdin 2018

1
@ErayErdin:ユースケースによって異なります。モジュールは警告だけでノイズ続いていると主張することができ、パフォーマンスの最適化としてインポートされている場合、それは確かではありません間違いのドキュメントのようにImportWarning示唆しています。
Martijn Pieters

3

これは、モジュールにインポート時の副作用がないことを前提として、一般的に安全です。

インポートされたモジュールがImportErrorインポート時に例外を(だけでなく)発生させた場合、そのモジュールはから削除されsys.modulesます。これは、他のコードがモジュールをインポートしようとした場合、部分的に初期化されたモジュールを取得しないことを意味します。代わりに、Pythonはモジュールをもう一度ロードしようとし、おそらくもう一度失敗しImportErrorます。

モジュールにインポート時の副作用がある場合、これらの効果は元に戻されないため、これにより問題が発生する可能性があります。特に、問題のあるモジュールが別のモジュールを正常にインポートした場合、後者はから削除されませんsys.modules。この特定の副作用が問題になることはめったにありませんが、一部の副作用はより厄介な場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.