31.4. 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可用于在执行代码之前预填充模块的全局字典。提供的字典不会被修改。如果在提供的字典中定义了下面的任何特殊全局变量,那么这些定义将被
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).__name__
is set to run_name if this optional argument is notNone
, tomod_name + '.__main__'
if the named module is a package and to the mod_name argument otherwise.__spec__
将为实际导入的模块(即__spec__.name
始终为mod_namemod_name + '.__ main __
,永远不要run_name)。__file__
,__cached__
,__loader__
and__package__
are set as normal based on the module spec.If the argument alter_sys is supplied and evaluates to
True
, thensys.argv[0]
is updated with the value of__file__
andsys.modules[__name__]
is updated with a temporary module object for the module being executed. 在函数返回之前,sys.argv[0]
和sys.modules[__name__]
都恢复为原始值。注意,对
sys
的这种操作不是线程安全的。其他线程可能会看到部分初始化的模块,以及更改的参数列表。当从线程代码调用此函数时,建议将sys
模块保留。也可以看看
-m
选项提供了与命令行相同的功能。在版本3.1中已更改:添加了通过查找
__main__
子模块来执行软件包的功能。在版本3.2中已更改:添加了
__cached__
全局变量(请参阅 PEP 3147)。在版本3.4中更改:已更新,以利用 PEP 451添加的模块规格功能。这允许为以这种方式运行的模块正确设置
__cached__
,以及确保实际模块名称总是作为__spec__.name
访问。
-
runpy.
run_path
(file_path, init_globals=None, run_name=None)¶ 在指定的文件系统位置执行代码,并返回结果模块全局字典。与提供给CPython命令行的脚本名称一样,提供的路径可以指代包含
__main__
模块的Python源文件,编译后的字节码文件或有效的sys.path条目。一个包含顶层__main__.py
文件的zip文件)。对于简单的脚本,指定的代码只是在一个新的模块命名空间中执行。对于有效的sys.path条目(通常为zipfile或目录),该条目首先添加到
sys.path
的开头。然后,该函数使用更新的路径查找并执行__main__
模块。请注意,如果在指定位置没有此类模块,则不会调用位于sys.path
上其他位置的现有__main__
条目的特殊保护。可选的字典参数init_globals可用于在执行代码之前预填充模块的全局字典。提供的字典不会被修改。如果在提供的字典中定义了下面的任何特殊全局变量,那么这些定义将被
run_path()
覆盖。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).如果此可选参数不是
None
和'<run_path>'
,则__name__
设置为run_name。如果提供的路径直接引用脚本文件(无论是作为源或预编译的字节代码),则
__file__
将设置为提供的路径,__spec__
,__cached__
,__loader__
和__package__
将全部设置为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__
和__package__
将被设置为set as normal还对
sys
模块进行了许多更改。首先,可以如上所述改变sys.path
。sys.argv[0]
is updated with the value offile_path
andsys.modules[__name__]
is updated with a temporary module object for the module being executed. 在sys
中对项目的所有修改都会在函数返回之前还原。请注意,与
run_module()
不同,对sys
所做的更改在此函数中不是可选的,因为这些调整对于允许执行sys.path条目至关重要。由于线程安全限制仍然适用,在线程代码中使用此函数应该与导入锁序列化或委派到单独的进程。也可以看看
Interface options用于命令行上的等效功能(
python path / to / script
)。版本3.2中的新功能。
在版本3.4中更改:已更新,以利用 PEP 451添加的模块规格功能。这允许在
__main__
从有效的sys.path条目导入而不是直接执行的情况下正确设置__cached__
。
也可以看看
- PEP 338 - 将模块作为脚本执行
- PEP由Nick Coghlan编写和实施。
- PEP 366 - 主模块显式相对导入
- PEP由Nick Coghlan编写和实施。
- PEP 451 - 导入系统的ModuleSpec类型
- PEP由Eric Snow编写和实施
Command line and environment - CPython命令行详细信息