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)

执行给定模块的代码,并返回结果模块的 globals 字典。 该模块的代码首先会用标准的导入机制去查找定位 (详情请参阅 PEP 302),然后在全新的模块命名空间中运行。

The mod_name argument should be an absolute module name. If the module name refers to a package rather than a normal module, then that package is imported and the __main__ submodule within that package is then executed and the resulting module globals dictionary returned.

可选的字典参数 init_globals 可用来在代码执行前预填充模块的 globals 字典。给出的字典参数不会被修改。如果字典中定义了以下任意一个特殊全局变量,这些定义都会被 run_module() 覆盖。

The special global variables __name__, __spec__, __file__, __cached__, __loader__ and __package__ are set in the globals dictionary before the module code is executed (Note that this is a minimal set of variables - other variables may be set implicitly as an interpreter implementation detail).

若可选参数 __name__ 不为 None 则设为 run_name,若此名称的模块是一个包则设为 mod_name + '.__main__',否则设为 mod_name 参数。

__spec__ 将设为合适的 实际 导入模块(也就是说,__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__] 将会复原。

Note that this manipulation of sys is not thread-safe. Other threads may see the partially initialised module, as well as the altered list of arguments. It is recommended that the sys module be left alone when invoking this function from threaded code.

参见

-m 选项由命令行提供相同功能。

在 3.1 版更改: Added ability to execute packages by looking for a __main__ submodule.

在 3.2 版更改: 加入了 __cached__ 全局变量(参见 PEP 3147 )。

在 3.4 版更改: 充分利用 PEP 451 加入的模块规格功能。使得以这种方式运行的模块能够正确设置 __cached__,并确保真正的模块名称总是可以通过 __spec__.name 的形式访问。

runpy.run_path(path_name, init_globals=None, run_name=None)

Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a compiled bytecode file or a valid sys.path entry containing a __main__ module (e.g. a zipfile containing a top-level __main__.py file).

For a simple script, the specified code is simply executed in a fresh module namespace. For a valid sys.path entry (typically a zipfile or directory), the entry is first added to the beginning of sys.path. The function then looks for and executes a __main__ module using the updated path. Note that there is no special protection against invoking an existing __main__ entry located elsewhere on sys.path if there is no such module at the specified location.

利用可选的字典参数 init_globals ,可在代码执行前预填模块的 globals 字典。给出的字典参数不会被修改。如果给出的字典中定义了下列特殊全局变量,这些定义均会被 run_module() 覆盖。

The special global variables __name__, __spec__, __file__, __cached__, __loader__ and __package__ are set in the globals dictionary before the module code is executed (Note that this is a minimal set of variables - other variables may be set implicitly as an interpreter implementation detail).

如果该可选参数不为 None,则 __name__ 被设为 run_name,否则为 '<run_path>'

如果提供的路径直接引用了一个脚本文件(无论是源码文件还是预编译的字节码),那么 __file__ 将设为给出的路径,而 __spec____cached____loader____package__ 都将设为 None

If the supplied path is a reference to a valid sys.path entry, then __spec__ will be set appropriately for the imported __main__ module (that is, __spec__.name will always be __main__). __file__, __cached__, __loader__ and __package__ will be set as normal based on the module spec.

A number of alterations are also made to the sys module. Firstly, sys.path may be altered as described above. sys.argv[0] is updated with the value of path_name and sys.modules[__name__] is updated with a temporary module object for the module being executed. All modifications to items in sys are reverted before the function returns.

Note that, unlike run_module(), the alterations made to sys are not optional in this function as these adjustments are essential to allowing the execution of sys.path entries. As the thread-safety limitations still apply, use of this function in threaded code should be either serialised with the import lock or delegated to a separate process.

参见

接口选项 用于在命令行上实现同等功能(python path/to/script)。

3.2 新版功能.

在 3.4 版更改: Updated to take advantage of the module spec feature added by PEP 451. This allows __cached__ to be set correctly in the case where __main__ is imported from a valid sys.path entry rather than being executed directly.

参见

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

PEP 由 Nick Coghlan 撰写并实现。

PEP 366 ——主模块的显式相对导入

PEP 由 Nick Coghlan 撰写并实现。

PEP 451 —— 导入系统采用的 ModuleSpec 类型

PEP 由 Eric Snow 撰写并实现。

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

importlib.import_module() 函数