# 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 コマンドライン詳細