Skip to main content

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_namemod_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.pathsys.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__

参见

PEP 338 - 将模块作为脚本执行

PEP由Nick Coghlan编写和实施。

PEP 366 - 主模块显式相对导入

PEP由Nick Coghlan编写和实施。

PEP 451 - 导入系统的ModuleSpec类型

PEP由Eric Snow编写和实施

命令行和环境 - CPython命令行详细信息

importlib.import_module() 功能