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

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


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

これはサンドボックスモジュール ではない ことに注意してください。すべてのコードは現在のプロセスで実行され、あらゆる副作用 (たとえば他のモジュールのキャッシュされたインポート等) は関数から戻った後にそのまま残ります。

さらに、 runpy 関数から戻った後で、実行されたコードによって定義された任意の関数およびクラスが正常に動作することは保証されません。この制限が受け入れられないユースケースでは、 importlib がこのモジュールより適切な選択となるでしょう。

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

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

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

The mod_name argument should be an absolute module name. If the module name refers to a package rather than a normal module, then that package is imported and the __main__ submodule within that package is then executed and the resulting module globals dictionary returned.

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

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

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

__spec__ will be set appropriately for the actually imported module (that is, __spec__.name will always be mod_name or mod_name + '.__main__, never run_name).

__file__, __cached__, __loader__ and __package__ are set as normal based on the module spec.

引数 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 で変更: Updated to take advantage of the module spec feature added by PEP 451. This allows __cached__ to be set correctly for modules run this way, as well as ensuring the real module name is always accessible as __spec__.name.

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

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

If the supplied path directly references a script file (whether as source or as precompiled byte code), then __file__ will be set to the supplied path, and __spec__, __cached__, __loader__ and __package__ will all be set to None.

If the supplied path is a reference to a valid sys.path entry, then __spec__ will be set appropriately for the imported __main__ module (that is, __spec__.name will always be __main__). __file__, __cached__, __loader__ and __package__ will be set as normal based on the module spec.

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

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

参考

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

バージョン 3.2 で追加.

バージョン 3.4 で変更: Updated to take advantage of the module spec feature added by PEP 451. This allows __cached__ to be set correctly in the case where __main__ is imported from a valid sys.path entry rather than being executed directly.

参考

PEP 338 - モジュールをスクリプトとして実行する
Nick Coghlan によって書かれ実装された PEP。
PEP 366 - main モジュールの明示的な相対インポート
Nick Coghlan によって書かれ実装された PEP。
PEP 451 -- A ModuleSpec Type for the Import System
PEP written and implemented by Eric Snow

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

importlib.import_module() 関数