imp —インポート内部にアクセスします—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/library/imp
移動先:案内検索

imp — import 内部にアクセスします

ソースコード: :source: `Lib / imp.py`

バージョン3.4以降非推奨: imp モジュールは非推奨になり、 importlib が優先されます。



このモジュールは、 import ステートメントを実装するために使用されるメカニズムへのインターフェースを提供します。 次の定数と関数を定義します。

imp.get_magic()

バイトコンパイルされたコードファイル(.pycファイル)の認識に使用されるマジックストリング値を返します。 (この値は、Pythonのバージョンごとに異なる場合があります。)

バージョン3.4以降非推奨:代わりに importlib.util.MAGIC_NUMBER を使用してください。

imp.get_suffixes()

それぞれが特定のタイプのモジュールを記述している3要素タプルのリストを返します。 各トリプルの形式は(suffix, mode, type)です。ここで、サフィックスは、検索するファイル名を形成するためにモジュール名に追加される文字列です。モードは、次のモード文字列です。組み込みの open()関数に渡してファイルを開き(テキストファイルの場合は'r'、バイナリファイルの場合は'rb')、タイプはファイルタイプであり、以下に説明する値 PY_SOURCEPY_COMPILED 、または C_EXTENSION のいずれかを持ちます。

バージョン3.3以降非推奨:代わりに importlib.machinery で定義された定数を使用してください。

imp.find_module(name[, path])

モジュール name を見つけてください。 path が省略されているかNoneの場合、sys.pathで指定されたディレクトリ名のリストが検索されますが、最初にいくつかの特別な場所が検索されます。 -指定された名前のモジュール( C_BUILTIN )、次にフリーズされたモジュール( PY_FROZEN )、および一部のシステムでは他の場所も調べられます(Windowsでは、特定のファイルを指す可能性のあるレジストリ)。

それ以外の場合、 path はディレクトリ名のリストである必要があります。 各ディレクトリで、上記の get_suffixes()によって返されるサフィックスのいずれかが付いたファイルが検索されます。 リスト内の無効な名前は黙って無視されます(ただし、すべてのリスト項目は文字列である必要があります)。

検索が成功した場合、戻り値は3要素のタプル(file, pathname, description)です。

file は、先頭にある開いている fileオブジェクトpathname は見つかったファイルのパス名、 description は3-です。見つかったモジュールの種類を説明する get_suffixes()によって返されるリストに含まれる要素タプル。

モジュールが組み込みまたはフリーズされている場合、 filepathname は両方ともNoneであり、 description タプルにはサフィックスとモード; モジュールタイプは、上記の括弧内に示されているように示されます。 検索が失敗した場合、 ImportError が発生します。 その他の例外は、引数または環境に問題があることを示しています。

モジュールがパッケージの場合、ファイルNoneパス名はパッケージパス、説明タプルの最後の項目はです。 ] PKG_DIRECTORY

この関数は、階層モジュール名(ドットを含む名前)を処理しません。 パッケージ PPM 、つまりサブモジュール M を見つけるには、 find_module()および load_module()を使用します。 を使用してパッケージ P を検索してロードし、 path 引数をP.__path__に設定して find_module()を使用します。 P 自体に点線の名前がある場合は、このレシピを再帰的に適用します。

バージョン3.3以降非推奨: Python 3.3との互換性が必要な場合を除き、代わりに importlib.util.find_spec()を使用してください。必要な場合は、 importlib.find_loader()を使用してください。 前者の使用例については、 importlib ドキュメントの Examples セクションを参照してください。

imp.load_module(name, file, pathname, description)

find_module()によって(または互換性のある結果を生成する他の方法で実行された検索によって)以前に検出されたモジュールをロードします。 この関数は、モジュールをインポートするだけではありません。モジュールがすでにインポートされている場合は、モジュールをリロードします。 name 引数は、完全なモジュール名を示します(これがパッケージのサブモジュールである場合は、パッケージ名を含みます)。 file 引数は開いているファイルであり、 pathname は対応するファイル名です。 モジュールがパッケージの場合、またはファイルからロードされていない場合、これらはそれぞれNoneおよびになります。 description 引数は、 get_suffixes()によって返されるタプルであり、ロードする必要のあるモジュールの種類を記述します。

ロードが成功した場合、戻り値はモジュールオブジェクトです。 それ以外の場合は、例外(通常は ImportError )が発生します。

重要:呼び出し元は、Noneでない場合、例外が発生した場合でも、ファイル引数を閉じる責任があります。 これは、 tryfinally ステートメントを使用して行うのが最適です。

バージョン3.3以降非推奨:以前に imp.find_module()と組み合わせて使用した場合は、 importlib.import_module()の使用を検討してください。それ以外の場合は、 imp.find_module()に選択した代替品。 imp.load_module()および関連する関数をファイルパス引数で直接呼び出した場合は、 importlib.util.spec_from_file_location()importlib.util.module_from_spec( )。 さまざまなアプローチの詳細については、 importlib ドキュメントの Examples セクションを参照してください。

imp.new_module(name)

name という新しい空のモジュールオブジェクトを返します。 このオブジェクトは、sys.modules挿入されていません

バージョン3.4以降非推奨:代わりに importlib.util.module_from_spec()を使用してください。

imp.reload(module)

以前にインポートしたモジュールをリロードします。 引数はモジュールオブジェクトである必要があるため、以前に正常にインポートされている必要があります。 これは、外部エディターを使用してモジュールのソースファイルを編集し、Pythonインタープリターを離れずに新しいバージョンを試してみたい場合に便利です。 戻り値はモジュールオブジェクトです( module 引数と同じ)。

reload(module)を実行した場合:

  • Pythonモジュールのコードが再コンパイルされ、モジュールレベルのコードが再実行され、モジュールのディクショナリ内の名前にバインドされるオブジェクトの新しいセットが定義されます。 拡張モジュールのinit関数は、2回目は呼び出されません。

  • Pythonの他のすべてのオブジェクトと同様に、古いオブジェクトは、参照カウントがゼロに低下した後にのみ再利用されます。

  • モジュール名前空間の名前は、新しいオブジェクトまたは変更されたオブジェクトを指すように更新されます。

  • 古いオブジェクトへの他の参照(モジュールの外部の名前など)は、新しいオブジェクトを参照するためにリバウンドされないため、必要に応じて、それらが発生する各名前空間で更新する必要があります。

他にもいくつかの注意点があります。

モジュールがリロードされると、そのディクショナリ(モジュールのグローバル変数を含む)が保持されます。 名前の再定義は古い定義を上書きするため、これは通常問題にはなりません。 モジュールの新しいバージョンで古いバージョンで定義された名前が定義されていない場合、古い定義が残ります。 この機能は、グローバルテーブルまたはオブジェクトのキャッシュを維持する場合にモジュールの利点として使用できます。 try ステートメントを使用して、テーブルの存在をテストし、必要に応じて初期化をスキップできます。

try:
    cache
except NameError:
    cache = {}

sys__ main __builtins を除いて、組み込みモジュールまたは動的にロードされたモジュールをリロードすることは一般的にあまり役に立ちませんが、合法です。 ただし、多くの場合、拡張モジュールは複数回初期化されるようには設計されておらず、リロード時に任意の方法で失敗する可能性があります。

モジュールが fromimport …を使用して別のモジュールからオブジェクトをインポートする場合、他のモジュールに対して reload()を呼び出しても、そのモジュールからインポートされたオブジェクトは再定義されません。これを回避する方法は、fromステートメントを再実行することです。別の方法は、代わりにimportと修飾名( module 。* name *)を使用することです。

モジュールがクラスのインスタンスをインスタンス化する場合、クラスを定義するモジュールをリロードしても、インスタンスのメソッド定義には影響しません。引き続き古いクラス定義を使用します。 同じことが派生クラスにも当てはまります。

バージョン3.3での変更:は、__name__だけでなく、リロードされるモジュールで定義されている__name____loader__の両方に依存します。

バージョン3.4以降非推奨:代わりに importlib.reload()を使用してください。

以下の関数は、 PEP 3147 バイトコンパイル済みファイルパスを処理するのに便利です。

バージョン3.2の新機能。


imp.cache_from_source(path, debug_override=None)

PEP 3147 パスを、ソースパスに関連付けられたバイトコンパイル済みファイルに返します。 たとえば、 path/foo/bar/baz.pyの場合、Python3.2の場合の戻り値は/foo/bar/__pycache__/baz.cpython-32.pycになります。 cpython-32文字列は、現在のマジックタグから取得されます( get_tag()を参照してください。sys.implementation.cache_tagが定義されていない場合、 NotImplementedError が発生します)。 debug_overrideTrueまたはFalseを渡すことで、__debug__のシステム値をオーバーライドして、バイトコードを最適化できます。

パスが存在する必要はありません。

バージョン3.3で変更: sys.implementation.cache_tagNoneの場合、 NotImplementedError が発生します。

バージョン3.4以降非推奨:代わりに importlib.util.cache_from_source()を使用してください。

バージョン3.5で変更: debug_override パラメーターは.pyoファイルを作成しなくなりました。

imp.source_from_cache(path)

パスから PEP 3147 ファイル名を指定して、関連するソースコードファイルパスを返します。 たとえば、 path/foo/bar/__pycache__/baz.cpython-32.pycの場合、返されるパスは/foo/bar/baz.pyになります。 path は存在する必要はありませんが、 PEP 3147 形式に準拠していない場合、 ValueError が発生します。 sys.implementation.cache_tagが定義されていない場合、 NotImplementedError が発生します。

バージョン3.3で変更:sys.implementation.cache_tagが定義されていない場合、 NotImplementedError を発生させます。

バージョン3.4以降非推奨:代わりに importlib.util.source_from_cache()を使用してください。

imp.get_tag()

get_magic()によって返される、このバージョンのPythonのマジックナンバーに一致する PEP 3147 マジックタグ文字列を返します。

バージョン3.4以降非推奨: Python3.3から直接sys.implementation.cache_tagを使用してください。

次の関数は、インポートシステムの内部ロックメカニズムとの対話に役立ちます。 インポートのロックセマンティクスは実装の詳細であり、リリースごとに異なる場合があります。 ただし、Pythonは、循環インポートがデッドロックなしで機能することを保証します。

imp.lock_held()

グローバルインポートロックが現在保持されている場合はTrueを返し、そうでない場合はFalseを返します。 スレッドのないプラットフォームでは、常にFalseを返します。

スレッドのあるプラットフォームでは、インポートを実行するスレッドは最初にグローバルインポートロックを保持し、次に残りのインポートのためにモジュールごとのロックを設定します。 これにより、元のインポートが完了するまで他のスレッドが同じモジュールをインポートするのをブロックし、他のスレッドが元のスレッドによって構築された不完全なモジュールオブジェクトを認識しないようにします。 循環インポートには例外があり、構造上、ある時点で不完全なモジュールオブジェクトを公開する必要があります。

バージョン3.3で変更:ロックスキームは、ほとんどの部分でモジュールごとのロックに変更されました。 モジュールごとのロックの初期化など、いくつかの重要なタスクのためにグローバルインポートロックが保持されます。

バージョン3.4以降非推奨。

imp.acquire_lock()

現在のスレッドのインタープリターのグローバルインポートロックを取得します。 このロックは、モジュールをインポートするときにスレッドセーフを確保するためにインポートフックで使用する必要があります。

スレッドがインポートロックを取得すると、同じスレッドがブロックせずに再度インポートロックを取得できます。 スレッドは、取得するたびに1回解放する必要があります。

スレッドのないプラットフォームでは、この関数は何もしません。

バージョン3.3で変更:ロックスキームは、ほとんどの部分でモジュールごとのロックに変更されました。 モジュールごとのロックの初期化など、いくつかの重要なタスクのためにグローバルインポートロックが保持されます。

バージョン3.4以降非推奨。

imp.release_lock()

インタプリタのグローバルインポートロックを解除します。 スレッドのないプラットフォームでは、この関数は何もしません。

バージョン3.3で変更:ロックスキームは、ほとんどの部分でモジュールごとのロックに変更されました。 モジュールごとのロックの初期化など、いくつかの重要なタスクのためにグローバルインポートロックが保持されます。

バージョン3.4以降非推奨。

このモジュールで定義されている整数値の次の定数は、 find_module()の検索結果を示すために使用されます。

imp.PY_SOURCE

モジュールがソースファイルとして見つかりました。

バージョン3.3以降非推奨。

imp.PY_COMPILED

モジュールは、コンパイルされたコードオブジェクトファイルとして見つかりました。

バージョン3.3以降非推奨。

imp.C_EXTENSION

モジュールは動的にロード可能な共有ライブラリとして見つかりました。

バージョン3.3以降非推奨。

imp.PKG_DIRECTORY

モジュールがパッケージディレクトリとして見つかりました。

バージョン3.3以降非推奨。

imp.C_BUILTIN

モジュールは組み込みモジュールとして見つかりました。

バージョン3.3以降非推奨。

imp.PY_FROZEN

モジュールがフリーズしたモジュールとして見つかりました。

バージョン3.3以降非推奨。

class imp.NullImporter(path_string)

NullImporter タイプは、 PEP 302 インポートフックであり、モジュールが見つからないためにディレクトリ以外のパス文字列を処理します。 既存のディレクトリまたは空の文字列を使用してこのタイプを呼び出すと、 ImportError が発生します。 それ以外の場合は、 NullImporter インスタンスが返されます。

インスタンスには1つのメソッドしかありません。

find_module(fullname[, path])

このメソッドは常にNoneを返し、要求されたモジュールが見つからなかったことを示します。

バージョン3.3で変更: NullImporter のインスタンスではなく、 Nonesys.path_importer_cacheに挿入されます。

バージョン3.4以降非推奨:代わりにNonesys.path_importer_cacheに挿入します。

次の関数は、Python 1.4までの標準のインポートステートメント(階層モジュール名なし)をエミュレートします。 ( find_module()が拡張され、 load_module()が1.4で追加されたため、この実装はそのバージョンでは機能しません。)

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()