"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)

   Execute the code of the specified module and return the resulting
   module globals dictionary. The module's code is first located using
   the standard import mechanism (refer to **PEP 302** for details)
   and then executed in a fresh module namespace.

   *mod_name* 参数应当是一个绝对模块名。 如果模块名指向一个包而非普通
   模块，则会导入这个包然后执行这个包中的 "__main__" 子模块再返回模块
   全局字典。

   The optional dictionary argument *init_globals* may be used to pre-
   populate the module's globals dictionary before the code is
   executed. The supplied dictionary will not be modified. If any of
   the special global variables below are defined in the supplied
   dictionary, those definitions are overridden by "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__" will be set appropriately for the *actually* imported
   module (that is, "__spec__.name" will always be *mod_name* or
   "mod_name + '.__main__", never *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" 的形式访问。

   在 3.12 版本发生变更: "__cached__", "__loader__" 和 "__package__"
   的设置已被弃用。 替代设置参见 "ModuleSpec"。

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).

   对于简单的脚本而言，只需在新的模块命名空间中执行指定的代码即可。 对
   于一个有效的 "sys.path" 条目（通常是一个 zip 文件或目录），首先会将
   该条目添加到 "sys.path" 的开头。 然后函数会使用更新后的路径查找并执
   行 "__main__" 模块。 请注意如果在指定的位置上没有 "__main__" 模块那
   么在发起调用位于 "sys.path" 中其他位置上的现有条目时也不会受到特殊
   保护。

   The optional dictionary argument *init_globals* may be used to pre-
   populate the module's globals dictionary before the code is
   executed. The supplied dictionary will not be modified. If any of
   the special global variables below are defined in the supplied
   dictionary, those definitions are overridden by "run_path()".

   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>'"。

   If the supplied path directly references a script file (whether as
   source or as precompiled byte code), then "__file__" will be set to
   the supplied path, and "__spec__", "__cached__", "__loader__" and
   "__package__" will all be set to "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.

   请注意，与 "run_module()" 不同，对 "sys" 的修改在本函数中不是可选项
   ，因为这些调整对于允许执行 "sys.path" 条目来说是至关重要的。 由于线
   程安全限制仍然适用，在线程代码中使用该函数应当使用导入锁进行序列化
   ，或是委托给单独的进程。

   参见: 接口选项 用于在命令行上实现同等功能（"python path/to/script"）。

   Added in version 3.2.

   在 3.4 版本发生变更: 进行更新以便利用 **PEP 451** 加入的模块规格特
   性。 这允许在 "__main__" 是从有效的 "sys.path" 条目导入而不是直接执
   行的情况下能够正确地设置 "__cached__"。

   在 3.12 版本发生变更: "__cached__", "__loader__" 和 "__package__"
   已被弃用。

参见:

  **PEP 338** -- 将模块作为脚本执行
     PEP 由 Nick Coghlan 撰写并实现。

  **PEP 366** ——主模块的显式相对导入
     PEP 由 Nick Coghlan 撰写并实现。

  **PEP 451** —— 导入系统采用的 ModuleSpec 类型
     PEP 由  Eric Snow 撰写并实现。

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

  "importlib.import_module()" 函数
