31.7. "runpy" --- Python モジュールの位置特定と実行
***************************************************

バージョン 2.5 で追加.

**ソースコード:** Lib/runpy.py

======================================================================

"runpy" モジュールは Python のモジュールをインポートせずにその位置を特
定したり実行したりするのに使われます。その主な目的はファイルシステムで
はなく Python のモジュール名前空間を使って位置を特定したスクリプトの実
行を可能にする "-m" コマンドラインスイッチを実装することです。

"runpy" モジュールは2つの関数を提供しています:

runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)

   指定されたモジュールのコードを実行し、実行後のモジュールグローバル
   辞書を返します。モジュールのコードはまず標準インポート機構(詳細は
   **PEP 302** を参照) を使ってモジュールの位置を特定され、まっさらな
   モジュール名前空間で実行されます。

   指定されたモジュール名が通常のモジュールではなくパッケージを参照し
   ていた場合、そのパッケージが import された後その中の "__main__" モ
   ジュールが実行され、実行後のモジュールグローバル辞書を返します。

   オプションの辞書型引数 *init_globals* はコードを実行する前にモジュ
   ールグローバル辞書に前もって必要な設定しておくのに使われます。与え
   られた辞書は変更されません。その辞書の中に以下に挙げる特別なグロー
   バル変数が定義されていたとしても、それらの定義は "run_module()" 関
   数によってオーバーライドされます。

   特別なグローバル変数 "__name__", "__file__", "__loader__",
   "__package__" はモジュールコードが実行される前にグローバル辞書にセ
   ットされます (この変数群は修正される最小セットです。これ以外の変数
   もインタプリタの実装の詳細として暗黙的に設定されるかもしれません)。

   "__name__" は、オプション引数 *run_name* が "None" でない場合、指定
   されたモジュールがパッケージであれば "mod_name + '.__main__'" に、
   そうでなければ *mod_name* 引数の値がセットされます。

   "__file__" はモジュールローダにより与えられた名前がセットされます。
   もしローダがファイル名情報を取得可能にしなければ、この変数の値は
   "None" になります。

   "__loader__" はモジュールのコードを取得するのに使われる **PEP 302**
   のモジュールローダがセットされます(このローダは標準のインポート機構
   に対するラッパーかもしれません)。

   "__package__" は指定されたモジュールがパッケージだった場合は
   *mod_name* に、それ以外の場合は "mod_name.rpartition('.')[0]" に設
   定されます。

   引数 *alter_sys* が与えられて "True" に評価されるならば、
   "sys.argv[0]" は "__file__" の値で更新され "sys.modules[__name__]"
   は実行されるモジュールの一時的モジュールオブジェクトで更新されます
   。 "sys.argv[0]" と "sys.modules[__name__]" はどちらも関数が処理を
   戻す前にもとの値に復旧します。

   この "sys" に対する操作はスレッドセーフではないということに注意して
   ください。他のスレッドは部分的に初期化されたモジュールを見たり、入
   れ替えられた引数リストを見たりするかもしれません。この関数をスレッ
   ド化されたコードから起動するときは "sys" モジュールには手を触れない
   ことが推奨されます。

   参考: コマンドラインから、 "-m" オプションを与えることで同じ機能
     を実現 出来ます。

   バージョン 2.7 で変更: "__main__" サブモジュールを検索することによ
   ってパッケージを実行する機能が追加されました。

runpy.run_path(file_path, init_globals=None, run_name=None)

   指定されたファイルシステム上の場所にあるコードを実行して、結果とし
   てそのモジュールグローバル辞書を返します。通常の CPython 実行時にコ
   マンドラインで指定するスクリプト名と同じく、指定できるパスは Python
   ソースファイル、コンパイルされたバイトコードファイル、もしくは
   "__main__" モジュールを含む有効な sys.path エントリ(例: トップレベ
   ルに "__main__.py" ファイルを持つ zip ファイル)です。

   シンプルなスクリプトを指定した場合は、指定されたコードはシンプルに
   新しいモジュール名前空間で実行されます。有効な sys.path エントリ (
   一般的には zip ファイルかディレクトリ) を指定した場合は、最初にその
   エントリが "sys.path" の先頭に追加されます。次に更新した "sys.path"
   を元に "__main__" モジュールを検索して実行します。指定された場所に
   "__main__" モジュールが無かった時、 "sys.path" のどこか他のエントリ
   に存在する別の "__main__" を実行してしまう可能性があることに注意し
   てください。

   オプションの辞書型引数 *init_globals* はコードを実行する前にモジュ
   ールグローバル辞書に前もって必要な設定しておくのに使われます。与え
   られた辞書は変更されません。その辞書の中に以下に挙げる特別なグロー
   バル変数が定義されていたとしても、それらの定義は "run_path()" 関数
   によってオーバーライドされます。

   特別なグローバル変数 "__name__", "__file__", "__loader__",
   "__package__" はモジュールコードが実行される前にグローバル辞書にセ
   ットされます (この変数群は修正される最小セットです。これ以外の変数
   もインタプリタの実装の詳細として暗黙的に設定されるかもしれません)。

   "__name__" は、オプション引数 *run_name* が "None" でない場合、
   *run_name* に設定され、それ以外の場合は "'<run_path>'" に設定されま
   す。

   "__file__" はモジュールローダにより与えられた名前がセットされます。
   もしローダがファイル名情報を取得可能にしなければ、この変数の値は
   "None" になります。シンプルなスクリプトの場合、これは "file_path"
   になるでしょう。

   "__loader__" はモジュールのコードを取得するのに使われる **PEP 302**
   のモジュールローダがセットされます(このローダは標準のインポート機構
   に対するラッパーかもしれません)。シンプルなスクリプトの場合、これは
   "None" になるでしょう。

   "__package__" は "__name__.rpartition('.')[0]" に設定されます。

   "sys" モジュールに対していくつかの変更操作が行われます。まず、
   "sys.path" が上記のように修正されます。 "sys.argv[0]" は
   "file_path" に更新され、 "sys.modules[__name__]" は実行されるモジュ
   ールのための一時モジュールオブジェクトに更新されます。 "sys" の要素
   に対する全ての変更は、この関数から戻る前に元に戻されます。

   "run_module()" と違い、 "sys" に対する変更はオプションではありませ
   ん。これらの変更は sys.path エントリの実行に必要不可欠だからです。
   スレッドセーフ性に関する制限はこの関数にも存在します。この関数をマ
   ルチスレッドプログラムから実行する場合は、 import lock によりシリア
   ライズして実行するか、別プロセスに委譲してください。

   参考: コマンドラインから インターフェイスオプション で同じ機能を
     使えま す ("python path/to/script")。

   バージョン 2.7 で追加.

参考:

  **PEP 338** - モジュールをスクリプトとして実行する
     Nick Coghlan によって書かれ実装された PEP。

  **PEP 366** - main モジュールの明示的な相対インポート
     Nick Coghlan によって書かれ実装された PEP。

  コマンドラインと環境 - CPython コマンドライン詳細
