31.4. runpy
—定位和执行Python模块¶
源代码: Lib/runpy.py
runpy
模块用于定位和运行Python模块,而不首先导入它们。它的主要用途是实现 -m
命令行开关,允许使用Python模块命名空间而不是文件系统来定位脚本。
注意,这是 not 的沙盒模块 - 所有代码在当前进程中执行,任何副作用(如其他模块的缓存导入)将在函数返回后保持原位。
此外,在 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()
覆盖。在执行模块代码之前,在全局变量字典中设置特殊的全局变量
__name__
,__spec__
,__file__
,__cached__
,__loader__
和__package__
(注意,这是一个最小的变量集合 - 其他变量可以隐式地设置为解释器实现细节) 。如果此可选参数不是
None
,则__name__
设置为 run_name,如果指定的模块是包,则设置为mod_name + '.__main__'
,否则设置为 mod_name 参数。__spec__
将针对 actually 导入模块进行适当设置(即,__spec__.name
将始终为 mod_name 或mod_name + '.__main__
,而不是 run_name)。__file__
,__cached__
,__loader__
和__package__
是基于模块规格的 设置为正常。如果提供参数 alter_sys 并且求值为
True
,则用__file__
的值更新sys.argv[0]
,并且用正在执行的模块的临时模块对象更新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
访问。
-
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()
覆盖。在执行模块代码之前,在全局变量字典中设置特殊的全局变量
__name__
,__spec__
,__file__
,__cached__
,__loader__
和__package__
(注意,这是一个最小的变量集合 - 其他变量可以隐式地设置为解释器实现细节) 。如果此可选参数不是
None
,则__name__
设置为 run_name,否则设置为'<run_path>'
。如果提供的路径直接引用脚本文件(无论是作为源还是作为预编译字节码),则
__file__
将被设置为提供的路径,__spec__
,__cached__
,__loader__
和__package__
将全部设置为None
。如果提供的路径是对有效sys.path条目的引用,则将为导入的
__main__
模块适当地设置__spec__
(即,__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__
。