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____cached____loader____package__ 在執行模組程式碼之前在全域性字典中設定。(請注意,這是一個最小的變數集 - 其他變數可能會作為直譯器實現的細節隱式設定。)

如果此可選引數不是 None,則 __name__ 設定為 run_name;如果命名模組是包,則設定為 mod_name + '.__main__',否則設定為 mod_name 引數。

__spec__ 將針對實際匯入的模組進行適當設定(也就是說,__spec__.name 將始終為 mod_namemod_name + '.__main__',而不是 run_name)。

__file____cached____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

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

執行指定檔案系統位置的程式碼,並返回生成的模組的全域性字典。與提供給 CPython 命令列的指令碼名稱一樣,file_path 可以引用 Python 原始碼檔案、編譯的位元組碼檔案或包含 __main__ 模組(例如,包含頂級 __main__.py 檔案的 zip 檔案)的有效 sys.path 條目。

對於一個簡單的指令碼,指定的程式碼只是在一個新的模組名稱空間中執行。對於一個有效的 sys.path 條目(通常是一個 zip 檔案或目錄),該條目首先被新增到 sys.path 的開頭。然後,該函式會查詢並使用更新後的路徑執行一個 __main__ 模組。請注意,如果沒有在指定位置找到這樣的模組,則不會對呼叫位於 sys.path 上其他位置的現有 __main__ 條目進行特殊保護。

可選的字典引數 init_globals 可用於在程式碼執行之前預先填充模組的全域性字典。init_globals 不會被修改。如果以下任何特殊全域性變數在 init_globals 中定義,這些定義會被 run_path() 覆蓋。

特殊全域性變數 __name____spec____file____cached____loader____package__ 在執行模組程式碼之前在全域性字典中設定。(請注意,這是一個最小的變數集 - 其他變數可能會作為直譯器實現的細節隱式設定。)

如果此可選引數不是 None,則 __name__ 被設定為 run_name,否則設定為 '<run_path>'

如果 file_path 直接引用指令碼檔案(無論是原始碼還是預編譯位元組碼),則 __file__ 將被設定為 file_path,而 __spec____cached____loader____package__ 都將被設定為 None

如果 file_path 是對有效 sys.path 條目的引用,則 __spec__ 將會為匯入的 __main__ 模組設定正確(也就是說,__spec__.name 將始終為 __main__)。__file____cached____loader____package__ 將根據模組規範正常設定

還對 sys 模組進行了一些更改。首先,sys.path 可能會如上所述被更改。sys.argv[0] 會更新為 file_path 的值,並且 sys.modules[__name__] 會更新為正在執行的模組的臨時模組物件。在函式返回之前,對 sys 中專案的全部修改都會被還原。

請注意,與 run_module() 不同,此函式中對 sys 所做的更改不是可選的,因為這些調整對於允許執行 sys.path 條目至關重要。由於執行緒安全的限制仍然適用,因此線上程程式碼中使用此函式時,應使用匯入鎖進行序列化,或者委託給單獨的程序。

另請參閱

在命令列上用於等效功能的介面選項python path/to/script)。

在 3.2 版本中新增。

在 3.4 版本中更改: 更新為利用 PEP 451 新增的模組規範特性。這允許在從有效的 sys.path 條目匯入 __main__ 而不是直接執行時,正確設定 __cached__

在 3.12 版本中更改: __cached____loader____package__ 的設定已棄用。

另請參閱

PEP 338 – 將模組作為指令碼執行

由 Nick Coghlan 編寫和實現的 PEP。

PEP 366 – 主模組的顯式相對匯入

由 Nick Coghlan 編寫和實現的 PEP。

PEP 451 – 用於匯入系統的 ModuleSpec 型別

由 Eric Snow 編寫和實現的 PEP

命令列和環境 - CPython 命令列詳細資訊

importlib.import_module() 函式