runpy — 定位并执行 Python 模块 — Python 文档
runpy — 定位和执行 Python 模块
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() 覆盖。
特殊全局变量
__name__
、__spec__
、__file__
、__cached__
、__loader__
和__package__
在全局变量中设置执行模块代码之前的字典(请注意,这是一个最小的变量集 - 其他变量可能被隐式设置为解释器实现细节)。__name__
设置为 run_name 如果此可选参数不是 None,如果命名模块是一个包和 设置为mod_name + '.__main__'
否则 mod_name 参数。__spec__
会为 actually 导入的模块适当设置(即__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
访问。
- runpy.run_path(file_path, init_globals=None, run_name=None)
在指定的文件系统位置执行代码并返回生成的模块全局字典。 与提供给 CPython 命令行的脚本名称一样,提供的路径可能指的是 Python 源文件、编译的字节码文件或包含
__main__
模块的有效 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__
都将设置为 无 。如果提供的路径是对有效 sys.path 条目的引用,则将为导入的
__main__
模块适当设置__spec__
(即,__spec__.name
将始终为 [ X173X])。__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 添加的模块规范功能。 这允许在
__main__
从有效的 sys.path 条目导入而不是直接执行的情况下正确设置__cached__
。