runpy
——查找并執(zhí)行 Python 模塊?
源代碼: Lib/runpy.py
runpy
模塊用于找到并運(yùn)行 Python 的模塊,而無(wú)需首先導(dǎo)入。主要用于實(shí)現(xiàn) -m
命令行開(kāi)關(guān),以允許用 Python 模塊命名空間而不是文件系統(tǒng)來(lái)定位腳本。
請(qǐng)注意,這 并非 一個(gè)沙盒模塊——所有代碼都在當(dāng)前進(jìn)程中運(yùn)行,所有副作用(如其他模塊對(duì)導(dǎo)入操作進(jìn)行了緩存)在函數(shù)返回后都會(huì)留存。
此外,在 runpy
函數(shù)返回后,任何由已執(zhí)行代碼定義的函數(shù)和類(lèi)都不能保證正確工作。如果某使用場(chǎng)景不能接收此限制,那么選用 importlib
可能更合適些。
runpy
模塊提供兩個(gè)函數(shù):
- runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)?
執(zhí)行給定模塊的代碼,并返回結(jié)果模塊的 globals 字典。 該模塊的代碼首先會(huì)用標(biāo)準(zhǔn)的導(dǎo)入機(jī)制去查找定位 (詳情請(qǐng)參閱 PEP 302),然后在全新的模塊命名空間中運(yùn)行。
參數(shù) mod_name 應(yīng)該是一個(gè)絕對(duì)模塊名。如果模塊名指向一個(gè)包,而不是普通的模塊,那么該包會(huì)被導(dǎo)入,然后執(zhí)行包中的
__main__
子模塊,并返回結(jié)果模塊的 globals 字典。可選的字典參數(shù) init_globals 可用來(lái)在代碼執(zhí)行前預(yù)填充模塊的 globals 字典。給出的字典參數(shù)不會(huì)被修改。如果字典中定義了以下任意一個(gè)特殊全局變量,這些定義都會(huì)被
run_module()
覆蓋。The special global variables
__name__
,__spec__
,__file__
,__cached__
,__loader__
and__package__
are set in the globals dictionary before the module code is executed (Note that this is a minimal set of variables - other variables may be set implicitly as an interpreter implementation detail).若可選參數(shù)
__name__
不為None
則設(shè)為 run_name,若此名稱(chēng)的模塊是一個(gè)包則設(shè)為mod_name + '.__main__'
,否則設(shè)為 mod_name 參數(shù)。__spec__
將設(shè)為合適的 實(shí)際 導(dǎo)入模塊(也就是說(shuō),__spec__.name
一定是 mod_name 或mod_name + '.__main__
,而不是 run_name)。__file__
、__cached__
、__loader__
和__package__
根據(jù)模塊規(guī)格進(jìn)行 常規(guī)設(shè)置如果給出了參數(shù) alter_sys 并且值為
True
,那么sys.argv[0]
將被更新為__file__
的值,sys.modules[__name__]
將被更新為臨時(shí)模塊對(duì)象。在函數(shù)返回前,sys.argv[0]
和sys.modules[__name__]
將會(huì)復(fù)原。注意,這種對(duì)
sys
的操作不是線程安全的。其他線程可能會(huì)看到初始化不完整的模塊,以及變動(dòng)后的參數(shù)列表。如果從線程中的代碼調(diào)用此函數(shù),建議單實(shí)例運(yùn)行sys
模塊。參見(jiàn)
-m
選項(xiàng)由命令行提供相同功能。在 3.1 版更改: 加入了 查找
__main__
子模塊并執(zhí)行軟件包的能力。在 3.2 版更改: 加入了
__cached__
全局變量(參見(jiàn) PEP 3147 )。在 3.4 版更改: 充分利用 PEP 451 加入的模塊規(guī)格功能。使得以這種方式運(yùn)行的模塊能夠正確設(shè)置
__cached__
,并確保真正的模塊名稱(chēng)總是可以通過(guò)__spec__.name
的形式訪問(wèn)。
- runpy.run_path(path_name, init_globals=None, run_name=None)?
執(zhí)行指定位置的代碼,并返回結(jié)果模塊的 globals 字典。與提供給 CPython 命令行的腳本名稱(chēng)一樣,給出的路徑可以指向 Python 源文件、編譯過(guò)的字節(jié)碼文件或包含``__main__`` 模塊的有效 sys.path 項(xiàng)(例如一個(gè)包含頂級(jí)``__main__.py`` 文件的 zip 文件)。
對(duì)于直接的腳本而言,指定代碼將直接在一個(gè)新的模塊命名空間中運(yùn)行。對(duì)于一個(gè)有效的 sys.path 項(xiàng)(通常是一個(gè) zip 文件或目錄),其首先會(huì)被添加到
sys.path
的開(kāi)頭。然后,本函數(shù)用更新后的路徑查找并執(zhí)行__main__
模塊。請(qǐng)注意,即便在指定位置不存在主模塊,也沒(méi)有特別的保護(hù)措施來(lái)防止調(diào)用存在于sys.path
其他地方的__main__
。利用可選的字典參數(shù) init_globals ,可在代碼執(zhí)行前預(yù)填模塊的 globals 字典。給出的字典參數(shù)不會(huì)被修改。如果給出的字典中定義了下列特殊全局變量,這些定義均會(huì)被
run_module()
覆蓋。The special global variables
__name__
,__spec__
,__file__
,__cached__
,__loader__
and__package__
are set in the globals dictionary before the module code is executed (Note that this is a minimal set of variables - other variables may be set implicitly as an interpreter implementation detail).如果該可選參數(shù)不為
None
,則__name__
被設(shè)為 run_name,否則為'<run_path>'
。如果提供的路徑直接引用了一個(gè)腳本文件(無(wú)論是源碼文件還是預(yù)編譯的字節(jié)碼),那么
__file__
將設(shè)為給出的路徑,而__spec__
、__cached__
、__loader__
和__package__
都將設(shè)為None
。如果給出的路徑是對(duì)有效 sys.path 項(xiàng)的引用,那么
__spec__
將為導(dǎo)入的__main__
模塊進(jìn)行正確設(shè)置 (也就是說(shuō),__spec__.name
將一定是__main__
)。__file__
,__cached__
,__loader__
和__package__
將依據(jù)模塊規(guī)格 進(jìn)行常規(guī)設(shè)置。A number of alterations are also made to the
sys
module. Firstly,sys.path
may be altered as described above.sys.argv[0]
is updated with the value ofpath_name
andsys.modules[__name__]
is updated with a temporary module object for the module being executed. All modifications to items insys
are reverted before the function returns.注意,與
run_module()
不同的是,本函數(shù)對(duì)sys
的修改不是可有可無(wú)的,因?yàn)檫@些調(diào)整對(duì)于 sys.path 項(xiàng)能夠順利執(zhí)行至關(guān)重要。由于依然存在線程安全的限制,在線程代碼中使用本函數(shù)時(shí)應(yīng)采用導(dǎo)入鎖進(jìn)行序列運(yùn)行,或者委托給一個(gè)單獨(dú)的進(jìn)程。參見(jiàn)
接口選項(xiàng) 用于在命令行上實(shí)現(xiàn)同等功能(
python path/to/script
)。3.2 新版功能.
在 3.4 版更改: 已作更新,以便充分利用 PEP 451 加入的模塊規(guī)格功能。使得從有效 sys.path 項(xiàng)導(dǎo)入``__main__`` 而不是直接執(zhí)行的情況下,能夠正確設(shè)置
__cached__
。
參見(jiàn)
- PEP 338 -- 將模塊作為腳本執(zhí)行
PEP 由 Nick Coghlan 撰寫(xiě)并實(shí)現(xiàn)。
- PEP 366 ——主模塊的顯式相對(duì)導(dǎo)入
PEP 由 Nick Coghlan 撰寫(xiě)并實(shí)現(xiàn)。
- PEP 451 —— 導(dǎo)入系統(tǒng)采用的 ModuleSpec 類(lèi)型
PEP 由 Eric Snow 撰寫(xiě)并實(shí)現(xiàn)。
命令行與環(huán)境 —— CPython 命令行詳解
importlib.import_module()
函數(shù)