runpy — 定位并执行 Python 模块 — Python 文档

来自菜鸟教程
Python/docs/3.8/library/runpy
跳转至:导航、​搜索

runpy — 定位和执行 Python 模块

源代码: :source:`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() 覆盖。

特殊全局变量 __name____spec____file____cached____loader____package__ 在全局变量中设置执行模块代码之前的字典(请注意,这是一个最小的变量集 - 其他变量可能被隐式设置为解释器实现细节)。

__name__ 如果此可选参数不是 None,则设置为 run_name,如果命名模块是包,则设置为 mod_name + '.__main__' 以及 否则 mod_name 参数。

__spec__ 会为 actually 导入的模块适当设置(即 __spec__.name 将始终为 mod_namemod_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.pathsys.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__

也可以看看

PEP 338 – 将模块作为脚本执行
PEP 由 Nick Coghlan 编写和实施。
PEP 366 – 主模块显式相关导入
PEP 由 Nick Coghlan 编写和实施。
PEP 451 – 导入系统的 ModuleSpec 类型
由 Eric Snow 编写和实施的 PEP

命令行与环境-CPython命令行详解

importlib.import_module() 函数