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_name 或mod_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.12 版本中更改:
__cached__
、__loader__
和__package__
的设置已弃用。