31.1. "imp" --- "import" 内部へアクセスする
*******************************************

このモジュールは "import" 文を実装するために使われているメカニズムへの
インターフェイスを提供します。次の定数と関数が定義されています:

imp.get_magic()

   バイトコンパイルされたコードファイル(".pyc" ファイル)を認識するため
   に使われるマジック文字列値を返します。 (この値は Python の各バージ
   ョンで異なります。)

imp.get_suffixes()

   3要素のタプルのリストを返します。それぞれのタプルは特定の種類のモジ
   ュールを説明しています。各タプルは "(suffix, mode, type)" という形
   式です。ここで、 *suffix* は探すファイル名を作るためにモジュール名
   に追加する文字列です。そのファイルをオープンするために、 *mode* は
   組み込み "open()" 関数へ渡されるモード文字列です (これはテキストフ
   ァイル対しては "'r'" 、バイナリファイルに対しては "'rb'" となります
   )。 *type* はファイル型で、以下で説明する値 "PY_SOURCE",
   "PY_COMPILED" あるいは、 "C_EXTENSION" の一つを取ります。

imp.find_module(name[, path])

   モジュール *name* を見つけようとします。 *path* が省略されるか
   "None" ならば、 "sys.path" によって与えられるディレクトリ名のリスト
   が検索されます。しかし、最初にいくつか特別な場所を検索します。まず
   、所定の名前をもつ組み込みモジュール("C_BUILTIN")を見つけようとしま
   す。それから、フリーズされたモジュール("PY_FROZEN")、そしていくつか
   のシステムでは他の場所が同様に検索されます (Windowsでは、特定のファ
   イルを指すレジストリの中を見ます)。

   それ以外の場合、 *path* はディレクトリ名のリストでなければなりませ
   ん。上の "get_suffixes()" が返す拡張子のいずれかを伴ったファイルを
   各ディレクトリの中で検索します。リスト内の有効でない名前は黙って無
   視されます(しかし、すべてのリスト項目は文字列でなければなりません)
   。

   検索が成功すれば、戻り値は3要素のタプル "(file, pathname,
   description)" です:

   *file* は先頭に位置合わせされたオープンファイルオブジェクトで、
   *pathname* は見つかったファイルのパス名です。そして、 *description*
   は "get_suffixes()" が返すリストに含まれているような3要素のタプルで
   、見つかったモジュールの種類を説明しています。

   モジュールがファイルとして存在していなければ、返された *file* は
   "None" で、 *pathname* は空文字列、 *description* タプルはその拡張
   子とモードに対して空文字列を含みます。モジュール型は上の括弧の中に
   示されます。検索が失敗すれば、 "ImportError" が発生します。他の例外
   は引数または環境に問題があることを示唆します。

   モジュールがパッケージならば、 *file* は "None" で、 *pathname* は
   パッケージのパスで *description* タプルの最後の項目は
   "PKG_DIRECTORY" です。

   この関数は階層的なモジュール名(ドットを含む名前)を扱いません。
   *P.M* 、すなわちパッケージ *P* のサブモジュール *M* を見つけるため
   には、まず "find_module()" と "load_module()" を使用してパッケージ
   *P* を見つけてロードして、次に "P.__path__" を *path* 引数にして
   "find_module()" を呼び出してください。もし *P* 自体がドット付きの名
   前を持つ場合、このレシピを再帰的に適用してください。

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

   "find_module()" を使って(あるいは、互換性のある結果を作り出す検索を
   行って)以前見つけたモジュールをロードします。この関数はモジュールを
   インポートするという以上のことを行います: モジュールが既にインポー
   トされているならば、 "reload()" と同じです! *name* 引数は(これがパ
   ッケージのサブモジュールならばパッケージ名を含む)完全なモジュール名
   を示します。 *file* 引数はオープンしたファイルで、 *pathname* は対
   応するファイル名です。モジュールがパッケージであるかファイルからロ
   ードされようとしていないとき、これらはそれぞれ "None" と "''" であ
   っても構いません。 "get_suffixes()" が返すように *description* 引数
   はタプルで、どの種類のモジュールがロードされなければならないかを説
   明するものです。

   ロードが成功したならば、戻り値はモジュールオブジェクトです。そうで
   なければ、例外(たいていは "ImportError")が発生します。

   **重要:** *file* 引数が "None" でなければ、例外が発生した場合でも呼
   び出し側にはそれを閉じる責任があります。これを行うには、 "try" ...
   "finally" 文を使うことが最も良いです。

imp.new_module(name)

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

imp.lock_held()

   現在インポートロックが維持されているならば、 "True" を返します。そ
   うでなければ、 "False" を返します。スレッドのないプラットホームでは
   、常に "False" を返します。

   スレッドのあるプラットホームでは、インポートが完了するまでインポー
   トを実行するスレッドは内部ロックを維持します。このロックは元のイン
   ポートが完了するまで他のスレッドがインポートすることを阻止します。
   言い換えると、元のスレッドがそのインポート(および、もしあるならば、
   それによって引き起こされるインポート) の途中で構築した不完全なモジ
   ュールオブジェクトを、他のスレッドが見られないようにします。

imp.acquire_lock()

   実行中のスレッドでインタープリタのインポートロックを取得します。イ
   ンポートフックは、スレッドセーフのためにこのロックを取得しなければ
   なりません。

   一旦スレッドがインポートロックを取得したら、その同じスレッドはブロ
   ックされることなくそのロックを再度取得できます。スレッドはロックを
   取得するのと同じだけ解放しなければなりません。

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

   バージョン 2.3 で追加.

imp.release_lock()

   インタープリタのインポートロックを解放します。スレッドのないプラッ
   トホームではこの関数は何もしません。

   バージョン 2.3 で追加.

整数値をもつ次の定数はこのモジュールの中で定義されており、
"find_module()" の検索結果を表すために使われます。

imp.PY_SOURCE

   ソースファイルとしてモジュールが発見された。

imp.PY_COMPILED

   コンパイルされたコードオブジェクトファイルとしてモジュールが発見さ
   れた。

imp.C_EXTENSION

   動的にロード可能な共有ライブラリとしてモジュールが発見された。

imp.PKG_DIRECTORY

   パッケージディレクトリとしてモジュールが発見された。

imp.C_BUILTIN

   モジュールが組み込みモジュールとして発見された。

imp.PY_FROZEN

   モジュールがフリーズされたモジュールとして発見された
   ("init_frozen()" を参照)。

以下の定数と関数は旧バージョンのものです。 "find_module()" や
"load_module()" を使えば同様の機能を利用できます。これらは後方互換性の
ために残されています:

imp.SEARCH_ERROR

   使われていません。

imp.init_builtin(name)

   *name* という名前の組み込みモジュールを初期化し、そのモジュールオブ
   ジェクトを "sys.modules" に格納した上で返します。モジュールが既に初
   期化されている場合は、 *再度* 初期化されます。再初期化は組み込みモ
   ジュールの "__dict__" を "sys.modules" のエントリーに結びつけられた
   キャッシュモジュールからコピーする過程を含みます。 *name* という名
   前の組み込みモジュールがない場合は、 "None" を返します。

imp.init_frozen(name)

   *name* という名前のフリーズされたモジュールを初期化し、モジュールオ
   ブジェクトを返します。モジュールが既に初期化されている場合は、 *再
   度* 初期化されます。 *name* という名前のフリーズされたモジュールが
   ない場合は、 "None" を返します。 (フリーズされたモジュールは Python
   で書かれたモジュールで、そのコンパイルされたバイトコードオブジェク
   トが Python の **freeze** ユーティリティを使ってカスタムビルド版の
   Python インタープリタへ組み込まれています。差し当たり、
   "Tools/freeze/" を参照してください。)

imp.is_builtin(name)

   *name* という名前の再初期化できる組み込みモジュールがある場合は、
   "1" を返します。 *name* という名前の再初期化できない組み込みモジュ
   ールがある場合は、 "-1" を返します ("init_builtin()" を参照してくだ
   さい)。 *name* という名前の組み込みモジュールがない場合は、 "0" を
   返します。

imp.is_frozen(name)

   *name* という名前のフリーズされたモジュール("init_frozen()" を参照)
   がある場合は、 "True" を返します。または、そのようなモジュールがな
   い場合は、 "False" を返します。

imp.load_compiled(name, pathname[, file])

   バイトコンパイルされたコードファイルとして実装されているモジュール
   をロードして初期化し、そのモジュールオブジェクトを返します。モジュ
   ールが既に初期化されている場合は、 *再度* 初期化されます。 *name*
   引数はモジュールオブジェクトを作ったり、アクセスするために使います
   。 *pathname* 引数はバイトコンパイルされたコードファイルを指します
   。 *file* 引数はバイトコンパイルされたコードファイルで、バイナリモ
   ードでオープンされ、先頭からアクセスされます。現在は、ユーザ定義の
   ファイルをエミュレートするクラスではなく、実際のファイルオブジェク
   トでなければなりません。

imp.load_dynamic(name, pathname[, file])

   動的ロード可能な共有ライブラリとして実装されているモジュールをロー
   ドして初期化します。モジュールが既に初期化されている場合は、 *再度*
   初期化します。再初期化はモジュールのキャッシュされたインスタンスの
   "__dict__" 属性を "sys.modules" にキャッシュされたモジュールの中で
   使われた値に上書きコピーする過程を含みます。 *pathname* 引数は共有
   ライブラリを指していなければなりません。 *name* 引数は初期化関数の
   名前を作るために使われます。共有ライブラリの "initname()" という名
   前の外部C関数が呼び出されます。オプションの *file* 引数は無視されま
   す。 (注意: 共有ライブラリはシステムに大きく依存します。また、すべ
   てのシステムがサポートしているわけではありません。)

   インポートの内部処理は拡張モジュールをファイル名で識別します。です
   から "foo = load_dynamic("foo", "mod.so")" と "bar =
   load_dynamic("bar", "mod.so")" では foo と bar のどちらも同じモジュ
   ールを参照します。 "mod.so" が "initbar" 関数を公開しているかどうか
   に無関係にです。シンボリックリンクをサポートするシステムでも、それ
   をすると、各々のモジュール参照が異なったファイル名を使って同じ共有
   ライブラリからの多重インポートになりえます。

imp.load_source(name, pathname[, file])

   Python ソースファイルとして実装されているモジュールをロードして初期
   化し、モジュールオブジェクトを返します。モジュールが既に初期化され
   ている場合は、 *再度* 初期化します。 *name* 引数はモジュールオブジ
   ェクトを作成したり、アクセスしたりするために使われます。 *pathname*
   引数はソースファイルを指します。 *file* 引数はソースファイルで、テ
   キストとして読み込むためにオープンされ、先頭からアクセスされます。
   現在は、ユーザ定義のファイルをエミュレートするクラスではなく、実際
   のファイルオブジェクトでなければなりません。 (拡張子 ".pyc" または
   ".pyo" をもつ)正しく対応するバイトコンパイルされたファイルが存在す
   る場合は、与えられたソースファイルを構文解析する代わりにそれが使わ
   れることに注意してください。

class imp.NullImporter(path_string)

   "NullImporter" 型は **PEP 302** インポートフックで、何もモジュール
   が見つからなかったときの非ディレクトリパス文字列を処理します。この
   型を既存のディレクトリや空文字列に対してコールすると "ImportError"
   が発生します。それ以外の場合は "NullImporter" のインスタンスが返さ
   れます。

   Python は、ディレクトリでなく "sys.path_hooks" のどのパスフックでも
   処理されていないすべてのパスエントリに対して、この型のインスタンス
   を "sys.path_importer_cache" に追加します。このインスタンスが持つメ
   ソッドは次のひとつです。

   find_module(fullname[, path])

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

   バージョン 2.5 で追加.


31.1.1. 例
==========

次の関数は Python 1.4 までの標準 import 文(階層的なモジュール名がない)
をエミュレートします。 (この *実装* はそのバージョンでは動作しないでし
ょう。なぜなら、 "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()

階層的なモジュール名を実装し、 "reload()" 関数を含むより完全な例はモジ
ュール "knee" にあります。 "knee" モジュールは Python のソースディスト
リビューションの中の "Demo/imputil/" にあります。
