runpy —查找和执行 Python 模块

源代码: Lib/runpy.py


runpy模块用于查找和运行 Python 模块,而无需先导入它们。它的主要用途是实现-m命令行开关,该开关允许使用 Python 模块名称空间而不是文件系统来定位脚本。

请注意,这不是沙箱模块-所有代码均在当前进程中执行,并且在函数返回后,任何副作用(例如其他模块的缓存导入)都将保留在原位。

此外,在返回runpy函数后,不能保证由执行的代码定义的任何函数和类均能正常工作。如果该限制对于给定的用例不可接受,则importlib可能是比此模块更合适的选择。

runpy模块提供两个Function:

  • 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 ;如果命名模块为包,则__name__设置为mod_name + '.__main__';否则将 mod_name *参数设置为mod_name + '.__main__'

__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的这种操作不是线程安全的。其他线程可能会看到部分初始化的模块,以及更改后的参数列表。从线程代码调用此Function时,建议不要单独使用sys模块。

See also

-m选项可从命令行提供等效Function。

在版本 3.1 中进行了更改:添加了pass查找__main__子模块来执行软件包的Function。

在版本 3.2 中进行了更改:添加了__cached__全局变量(请参见 PEP 3147)。

在版本 3.4 中进行了更改:已更新,以利用 PEP 451添加的模块规范Function。这样就可以为以这种方式运行的模块正确设置__cached__,并确保始终以__spec__.name的形式访问实际模块名称。

  • runpy. run_path(* file_path init_globals = None run_name = None *)
    • 在指定的文件系统位置执行代码,并返回生成的模块全局字典。与提供给 CPython 命令行的脚本名称一样,提供的路径可能指向 Python 源文件,编译的字节码文件或包含__main__模块的有效 sys.path 条目(例如,包含顶级__main__.py文件的 zipfile) 。

对于简单的脚本,只需在新的模块名称空间中执行指定的代码。对于有效的 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.path。使用file_path的值更新sys.argv[0],使用正在执行的模块的临时模块对象更新sys.modules[__name__]。函数返回之前,对sys中项目的所有修改都将还原。

请注意,与run_module()不同的是,对sys所做的更改在此函数中不是可选的,因为这些调整对于允许执行 sys.path 项至关重要。由于线程安全限制仍然适用,因此应在线程代码中使用导入锁序列化此函数,或将其委派给单独的进程。

See also

Interface options代表命令行上的等效Function(python path/to/script)。

3.2 版中的新Function。

在版本 3.4 中进行了更改:已更新,以利用 PEP 451添加的模块规范Function。如果从有效的 sys.path 条目导入__main__而不是直接执行__main__,则可以正确设置__cached__

See also

  • PEP 338 –将模块作为脚本执行

  • PEP 由 Nick Coghlan 编写和实施。

  • PEP 366 –主模块显式相对导入

  • PEP 由 Nick Coghlan 编写和实施。

  • PEP 451 –导入系统的 ModuleSpec 类型

  • 由 Eric Snow 编写并实施的 PEP

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

importlib.import_module()Function