runpy --- Python モジュールの位置特定と実行¶
ソースコード: Lib/runpy.py
runpy モジュールは、Python モジュールをあらかじめインポートせずに見つけて実行するために使います。
主な用途はコマンドラインオプション -m の実装です。
このオプションを使うと、ファイルシステムではなく Python のモジュール名前空間からスクリプトを探せます。
これはサンドボックスモジュール ではない ことに注意してください。すべてのコードは現在のプロセスで実行され、あらゆる副作用 (たとえば他のモジュールのキャッシュされたインポート等) は関数から戻った後にそのまま残ります。
さらに、実行したコードで定義された関数やクラスが runpy の関数から戻った後も正しく動作する保証はありません。
この制約が用途に合わない場合は、このモジュールより importlib の方が適しているでしょう。
runpy モジュールは二つの関数を提供します。
- runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)¶
指定したモジュールのコードを実行し、実行後のモジュールのグローバル変数の辞書を返します。 まず標準のインポート機構 (詳細は PEP 302 を参照) でモジュールのコードを探し、新しいモジュール名前空間で実行します。
mod_name 引数には絶対モジュール名を指定します。 モジュール名が通常のモジュールではなくパッケージを指す場合は、そのパッケージをインポートしてから、パッケージ内の
__main__サブモジュールを実行し、実行後のモジュールのグローバル変数の辞書を返します。省略可能な辞書引数 init_globals を使うと、コードの実行前にモジュールのグローバル変数の辞書に値を設定できます。 init_globals 自体は変更されません。 以下の特殊なグローバル変数が init_globals に定義されている場合、その定義は
run_module()によって上書きされます。モジュールのコードを実行する前に、特殊なグローバル変数
__name__、__spec__、__file__、__loader__、__package__がグローバル変数の辞書に設定されます。 (これは最低限の変数の組であり、インタープリタの実装の詳細として他の変数が暗黙に設定される場合もあります。)__name__は、 run_name がNoneでない場合は run_name に設定されます。 run_name がNoneである場合、 mod_name がパッケージであればmod_name + '.__main__'に、それ以外では mod_name に設定されます。__spec__には 実際に インポートするモジュールに適した値を設定します (つまり、__spec__.nameは常に mod_name またはmod_name + '.__main__'であり、run_name になることはありません)。__file__、__loader__、__package__はモジュール仕様に基づき 通常どおり設定されます。引数 alter_sys が与えられて
Trueに評価されるならば、sys.argv[0]は__file__の値で更新されsys.modules[__name__]は実行されるモジュールの一時的モジュールオブジェクトで更新されます。sys.argv[0]とsys.modules[__name__]はどちらも関数が処理を戻す前にもとの値に復旧します。この
sysの操作はスレッドセーフではありません。 他のスレッドからは、初期化途中のモジュールや変更された引数リストが見える場合があります。 スレッドを使うコードからこの関数を呼び出す場合は、sysモジュールを変更しないことをお勧めします。参考
コマンドラインから、
-mオプションを与えることで同じ機能を実現出来ます。バージョン 3.1 で変更:
__main__サブモジュールを探してパッケージを実行する機能が追加されました。バージョン 3.2 で変更:
__cached__グローバル変数が追加されました (PEP 3147 を参照)。バージョン 3.4 で変更: PEP 451 で追加されたモジュール仕様の機能を活用するよう更新されました。 これにより、この方法で実行したモジュールの
__cached__を正しく設定できるようになり、実際のモジュール名を常に__spec__.nameで取得できるようになりました。バージョン 3.12 で変更:
__cached__、__loader__、__package__の設定は非推奨になりました。 代わりの方法についてはModuleSpecを参照してください。バージョン 3.15 で変更: グローバル変数
__cached__は設定されなくなりました。
- runpy.run_path(path_name, init_globals=None, run_name=None)¶
指定したファイルシステム上の場所にあるコードを実行し、実行後のモジュールのグローバル変数の辞書を返します。 CPython のコマンドラインに渡すスクリプト名と同様、file_path には Python ソースファイル、コンパイル済みのバイトコードファイル、または
__main__モジュールを含む有効なsys.pathエントリー (例えば最上位に__main__.pyがある zip ファイル) を指定できます。単純なスクリプトの場合は、指定されたコードを新しいモジュール名前空間で実行するだけです。 有効な
sys.pathエントリー (通常は zip ファイルまたはディレクトリ) の場合は、まずそのエントリーをsys.pathの先頭に追加します。 次に、更新されたパスを使って__main__モジュールを探し、実行します。 指定した場所にそのモジュールがない場合、sys.path上の別の場所にある既存の__main__を実行しないようにする特別な保護はありません。省略可能な辞書引数 init_globals を使うと、コードの実行前にモジュールのグローバル変数の辞書に値を設定できます。 init_globals 自体は変更されません。 以下の特殊なグローバル変数が init_globals に定義されている場合、その定義は
run_path()によって上書きされます。モジュールのコードを実行する前に、特殊なグローバル変数
__name__、__spec__、__file__、__loader__、__package__がグローバル変数の辞書に設定されます。 (これは最低限の変数の組であり、インタープリタの実装の詳細として他の変数が暗黙に設定される場合もあります。)__name__は、オプション引数 run_name がNoneでない場合は run_name に設定されます。 run_name がNoneの場合は'<run_path>'に設定されます。file_path がスクリプトファイル (ソースまたはコンパイル済みのバイトコード) を直接指す場合、
__file__は file_path に設定され、__spec__、__loader__、__package__はすべてNoneに設定されます。file_path が有効な
sys.pathエントリーを指す場合、__spec__にはインポートする__main__モジュールに適した値を設定します (つまり、__spec__.nameは常に__main__です)。__file__、__loader__、__package__はモジュール仕様に基づき 通常どおり設定されます。sysモジュールにもいくつかの変更を加えます。 まず、上述のようにsys.pathを変更する場合があります。sys.argv[0]を file_path の値に更新し、sys.modules[__name__]を実行対象のモジュールを表す一時的なモジュールオブジェクトに更新します。sys内の要素への変更はすべて、関数から戻る前に元に戻します。run_module()とは異なり、この関数ではsysへの変更を省略できません。sys.pathエントリーの実行にはこれらの変更が必要なためです。 スレッドセーフに関する制約も同様にあるため、スレッドを使うコードでこの関数を使う場合は、インポートロックで実行を直列化するか、別のプロセスに実行を委ねてください。参考
コマンドラインから インターフェイスオプション で同じ機能を使えます (
python path/to/script)。Added in version 3.2.
バージョン 3.4 で変更: PEP 451 で追加されたモジュール仕様の機能を活用するよう更新されました。 これにより、
__main__を直接実行するのではなく有効なsys.pathエントリーからインポートする場合に、__cached__を正しく設定できるようになりました。バージョン 3.12 で変更:
__cached__、__loader__、__package__の設定は非推奨になりました。バージョン 3.15 で変更: グローバル変数
__cached__は設定されなくなりました。
参考
- PEP 338 - モジュールをスクリプトとして実行する
PEP written and implemented by Nick Coghlan.
- PEP 366 - main モジュールの明示的な相対インポート
PEP written and implemented by Nick Coghlan.
- PEP 451 -- インポートシステムのための ModuleSpec 型
PEP written and implemented by Eric Snow
コマンドラインと環境 - CPython コマンドライン詳細