2019-04-08 23:22:26 +08:00

1 line
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="body" role="main"><div class="section" id="module-runpy"><h1><span class="yiyi-st" id="yiyi-10">31.4. <a class="reference internal" href="#module-runpy" title="runpy: Locate and run Python modules without importing them first."><code class="xref py py-mod docutils literal"><span class="pre">runpy</span></code></a> - 定位和执行Python模块</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/runpy.py">Lib / runpy.py</a></span></p><p><span class="yiyi-st" id="yiyi-12"><a class="reference internal" href="#module-runpy" title="runpy: Locate and run Python modules without importing them first."><code class="xref py py-mod docutils literal"><span class="pre">runpy</span></code></a>模块用于定位和运行Python模块而不首先导入它们。</span><span class="yiyi-st" id="yiyi-13">它的主要用途是实现<a class="reference internal" href="../using/cmdline.html#cmdoption-m"><code class="xref std std-option docutils literal"><span class="pre">-m</span></code></a>命令行开关它允许使用Python模块命名空间而不是文件系统来定位脚本。</span></p><p><span class="yiyi-st" id="yiyi-14">请注意,这<em>不是</em>沙盒模块 - 所有代码都在当前进程中执行,任何副作用(如其他模块的缓存导入)将在函数返回后保持原位。</span></p><p><span class="yiyi-st" id="yiyi-15">此外,在返回<a class="reference internal" href="#module-runpy" title="runpy: Locate and run Python modules without importing them first."><code class="xref py py-mod docutils literal"><span class="pre">runpy</span></code></a>函数之后,由执行代码定义的任何函数和类都不能保证正常工作。</span><span class="yiyi-st" id="yiyi-16">如果该限制对于给定的用例是不可接受的,则<a class="reference internal" href="importlib.html#module-importlib" title="importlib: The implementation of the import machinery."><code class="xref py py-mod docutils literal"><span class="pre">importlib</span></code></a>可能是比这个模块更合适的选择。</span></p><p><span class="yiyi-st" id="yiyi-17"><a class="reference internal" href="#module-runpy" title="runpy: Locate and run Python modules without importing them first."><code class="xref py py-mod docutils literal"><span class="pre">runpy</span></code></a>模块提供两个功能:</span></p><dl class="function"><dt id="runpy.run_module"><span class="yiyi-st" id="yiyi-18"> <code class="descclassname">runpy.</code><code class="descname">run_module</code><span class="sig-paren">(</span><em>mod_name</em>, <em>init_globals=None</em>, <em>run_name=None</em>, <em>alter_sys=False</em><span class="sig-paren">)</span></span></dt><dd><p id="index-0"><span class="yiyi-st" id="yiyi-19">执行指定模块的代码,并返回结果模块全局字典。</span><span class="yiyi-st" id="yiyi-20">模块的代码首先使用标准导入机制来定位(有关详细信息,请参阅<span class="target" id="index-1"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0302"><strong>PEP 302</strong></a>),然后在新的模块命名空间中执行。</span></p><p><span class="yiyi-st" id="yiyi-21"><em>mod_name</em>参数应为绝对模块名称。</span><span class="yiyi-st" id="yiyi-22">如果模块名称引用了一个包而不是普通模块,那么将导入该包,然后执行该包内的<code class="docutils literal"><span class="pre">__main__</span></code>子模块,并返回生成的模块全局字典。</span></p><p><span class="yiyi-st" id="yiyi-23">可选的字典参数<em>init_globals</em>可用于在执行代码之前预填充模块的全局字典。</span><span class="yiyi-st" id="yiyi-24">提供的字典不会被修改。</span><span class="yiyi-st" id="yiyi-25">如果在提供的字典中定义了下面的任何特殊全局变量,那么这些定义将被<a class="reference internal" href="#runpy.run_module" title="runpy.run_module"><code class="xref py py-func docutils literal"><span class="pre">run_module()</span></code></a>覆盖。</span></p><p><span class="yiyi-st" id="yiyi-26">The special global variables <code class="docutils literal"><span class="pre">__name__</span></code>, <code class="docutils literal"><span class="pre">__spec__</span></code>, <code class="docutils literal"><span class="pre">__file__</span></code>, <code class="docutils literal"><span class="pre">__cached__</span></code>, <code class="docutils literal"><span class="pre">__loader__</span></code> and <code class="docutils literal"><span class="pre">__package__</span></code> 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).</span></p><p><span class="yiyi-st" id="yiyi-27"><code class="docutils literal"><span class="pre">__name__</span></code> is set to <em>run_name</em> if this optional argument is not <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>, to <code class="docutils literal"><span class="pre">mod_name</span> <span class="pre">+</span> <span class="pre">'.__main__'</span></code> if the named module is a package and to the <em>mod_name</em> argument otherwise.</span></p><p><span class="yiyi-st" id="yiyi-28"><code class="docutils literal"><span class="pre">__spec__</span></code>将为<em>实际</em>导入的模块(即<code class="docutils literal"><span class="pre">__spec__.name</span></code>始终为<em>mod_name</em> <code class="docutils literal"><span class="pre">mod_name</span> <span class="pre">+</span> <span class="pre">'.__ main __</span></code>,永远不要<em>run_name</em>)。</span></p><p><span class="yiyi-st" id="yiyi-29"><code class="docutils literal"><span class="pre">__file__</span></code>, <code class="docutils literal"><span class="pre">__cached__</span></code>, <code class="docutils literal"><span class="pre">__loader__</span></code> and <code class="docutils literal"><span class="pre">__package__</span></code> are <a class="reference internal" href="../reference/import.html#import-mod-attrs"><span>set as normal</span></a> based on the module spec.</span></p><p><span class="yiyi-st" id="yiyi-30">If the argument <em>alter_sys</em> is supplied and evaluates to <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>, then <code class="docutils literal"><span class="pre">sys.argv[0]</span></code> is updated with the value of <code class="docutils literal"><span class="pre">__file__</span></code> and <code class="docutils literal"><span class="pre">sys.modules[__name__]</span></code> is updated with a temporary module object for the module being executed. </span><span class="yiyi-st" id="yiyi-31">在函数返回之前,<code class="docutils literal"><span class="pre">sys.argv[0]</span></code><code class="docutils literal"><span class="pre">sys.modules[__name__]</span></code>都恢复为原始值。</span></p><p><span class="yiyi-st" id="yiyi-32">注意,对<a class="reference internal" href="sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal"><span class="pre">sys</span></code></a>的这种操作不是线程安全的。</span><span class="yiyi-st" id="yiyi-33">其他线程可能会看到部分初始化的模块,以及更改的参数列表。</span><span class="yiyi-st" id="yiyi-34">当从线程代码调用此函数时,建议将<a class="reference internal" href="sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal"><span class="pre">sys</span></code></a>模块保留。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-35">也可以看看</span></p><p class="last"><span class="yiyi-st" id="yiyi-36"><a class="reference internal" href="../using/cmdline.html#cmdoption-m"><code class="xref std std-option docutils literal"><span class="pre">-m</span></code></a>选项提供了与命令行相同的功能。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-37"><span class="versionmodified">在版本3.1中已更改:</span>添加了通过查找<code class="docutils literal"><span class="pre">__main__</span></code>子模块来执行软件包的功能。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-38"><span class="versionmodified">在版本3.2中已更改:</span>添加了<code class="docutils literal"><span class="pre">__cached__</span></code>全局变量(请参阅<span class="target" id="index-2"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a>)。</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-39"><span class="versionmodified">在版本3.4中更改:</span>已更新,以利用<span class="target" id="index-3"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0451"><strong>PEP 451</strong></a>添加的模块规格功能。</span><span class="yiyi-st" id="yiyi-40">这允许为以这种方式运行的模块正确设置<code class="docutils literal"><span class="pre">__cached__</span></code>,以及确保实际模块名称总是作为<code class="docutils literal"><span class="pre">__spec__.name</span></code>访问。</span></p></div></dd></dl><dl class="function"><dt id="runpy.run_path"><span class="yiyi-st" id="yiyi-41"> <code class="descclassname">runpy.</code><code class="descname">run_path</code><span class="sig-paren">(</span><em>file_path</em>, <em>init_globals=None</em>, <em>run_name=None</em><span class="sig-paren">)</span></span></dt><dd><p id="index-4"><span class="yiyi-st" id="yiyi-42">在指定的文件系统位置执行代码,并返回结果模块全局字典。</span><span class="yiyi-st" id="yiyi-43">与提供给CPython命令行的脚本名称一样提供的路径可以指代包含<code class="docutils literal"><span class="pre">__main__</span></code>模块的Python源文件编译后的字节码文件或有效的sys.path条目。</span><span class="yiyi-st" id="yiyi-44">一个包含顶层<code class="docutils literal"><span class="pre">__main__.py</span></code>文件的zip文件</span></p><p><span class="yiyi-st" id="yiyi-45">对于简单的脚本,指定的代码只是在一个新的模块命名空间中执行。</span><span class="yiyi-st" id="yiyi-46">对于有效的sys.path条目通常为zipfile或目录该条目首先添加到<code class="docutils literal"><span class="pre">sys.path</span></code>的开头。</span><span class="yiyi-st" id="yiyi-47">然后,该函数使用更新的路径查找并执行<a class="reference internal" href="__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal"><span class="pre">__main__</span></code></a>模块。</span><span class="yiyi-st" id="yiyi-48">请注意,如果在指定位置没有此类模块,则不会调用位于<code class="docutils literal"><span class="pre">sys.path</span></code>上其他位置的现有<a class="reference internal" href="__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal"><span class="pre">__main__</span></code></a>条目的特殊保护。</span></p><p><span class="yiyi-st" id="yiyi-49">可选的字典参数<em>init_globals</em>可用于在执行代码之前预填充模块的全局字典。</span><span class="yiyi-st" id="yiyi-50">提供的字典不会被修改。</span><span class="yiyi-st" id="yiyi-51">如果在提供的字典中定义了下面的任何特殊全局变量,那么这些定义将被<a class="reference internal" href="#runpy.run_path" title="runpy.run_path"><code class="xref py py-func docutils literal"><span class="pre">run_path()</span></code></a>覆盖。</span></p><p><span class="yiyi-st" id="yiyi-52">The special global variables <code class="docutils literal"><span class="pre">__name__</span></code>, <code class="docutils literal"><span class="pre">__spec__</span></code>, <code class="docutils literal"><span class="pre">__file__</span></code>, <code class="docutils literal"><span class="pre">__cached__</span></code>, <code class="docutils literal"><span class="pre">__loader__</span></code> and <code class="docutils literal"><span class="pre">__package__</span></code> 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).</span></p><p><span class="yiyi-st" id="yiyi-53">如果此可选参数不是<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a><code class="docutils literal"><span class="pre">'&lt;run_path&gt;'</span></code>,则<code class="docutils literal"><span class="pre">__name__</span></code>设置为<em>run_name</em></span></p><p><span class="yiyi-st" id="yiyi-54">如果提供的路径直接引用脚本文件(无论是作为源或预编译的字节代码),则<code class="docutils literal"><span class="pre">__file__</span></code>将设置为提供的路径,<code class="docutils literal"><span class="pre">__spec__</span></code><code class="docutils literal"><span class="pre">__cached__</span></code><code class="docutils literal"><span class="pre">__loader__</span></code><code class="docutils literal"><span class="pre">__package__</span></code>将全部设置为<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-55">If the supplied path is a reference to a valid sys.path entry, then <code class="docutils literal"><span class="pre">__spec__</span></code> will be set appropriately for the imported <code class="docutils literal"><span class="pre">__main__</span></code> module (that is, <code class="docutils literal"><span class="pre">__spec__.name</span></code> will always be <code class="docutils literal"><span class="pre">__main__</span></code>). </span><span class="yiyi-st" id="yiyi-56"><code class="docutils literal"><span class="pre">__file__</span></code><code class="docutils literal"><span class="pre">__cached__</span></code><code class="docutils literal"><span class="pre">__loader__</span></code><code class="docutils literal"><span class="pre">__package__</span></code>将被设置为<a class="reference internal" href="../reference/import.html#import-mod-attrs"><span>set as normal</span></a></span></p><p><span class="yiyi-st" id="yiyi-57">还对<a class="reference internal" href="sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal"><span class="pre">sys</span></code></a>模块进行了许多更改。</span><span class="yiyi-st" id="yiyi-58">首先,可以如上所述改变<code class="docutils literal"><span class="pre">sys.path</span></code></span><span class="yiyi-st" id="yiyi-59"><code class="docutils literal"><span class="pre">sys.argv[0]</span></code> is updated with the value of <code class="docutils literal"><span class="pre">file_path</span></code> and <code class="docutils literal"><span class="pre">sys.modules[__name__]</span></code> is updated with a temporary module object for the module being executed. </span><span class="yiyi-st" id="yiyi-60"><a class="reference internal" href="sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal"><span class="pre">sys</span></code></a>中对项目的所有修改都会在函数返回之前还原。</span></p><p><span class="yiyi-st" id="yiyi-61">请注意,与<a class="reference internal" href="#runpy.run_module" title="runpy.run_module"><code class="xref py py-func docutils literal"><span class="pre">run_module()</span></code></a>不同,对<a class="reference internal" href="sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal"><span class="pre">sys</span></code></a>所做的更改在此函数中不是可选的因为这些调整对于允许执行sys.path条目至关重要。</span><span class="yiyi-st" id="yiyi-62">由于线程安全限制仍然适用,在线程代码中使用此函数应该与导入锁序列化或委派到单独的进程。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-63">也可以看看</span></p><p class="last"><span class="yiyi-st" id="yiyi-64"><a class="reference internal" href="../using/cmdline.html#using-on-interface-options"><span>Interface options</span></a>用于命令行上的等效功能(<code class="docutils literal"><span class="pre">python</span> <span class="pre">path / to / script</span></code>)。</span></p></div><div class="versionadded"><p><span class="yiyi-st" id="yiyi-65"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-66"><span class="versionmodified">在版本3.4中更改:</span>已更新,以利用<span class="target" id="index-5"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0451"><strong>PEP 451</strong></a>添加的模块规格功能。</span><span class="yiyi-st" id="yiyi-67">这允许在<code class="docutils literal"><span class="pre">__main__</span></code>从有效的sys.path条目导入而不是直接执行的情况下正确设置<code class="docutils literal"><span class="pre">__cached__</span></code></span></p></div></dd></dl><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-68">也可以看看</span></p><dl class="docutils"><dt><span class="yiyi-st" id="yiyi-69"><span class="target" id="index-6"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0338"><strong>PEP 338</strong></a> - 将模块作为脚本执行</span></dt><dd><span class="yiyi-st" id="yiyi-70">PEP由Nick Coghlan编写和实施。</span></dd><dt><span class="yiyi-st" id="yiyi-71"><span class="target" id="index-7"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0366"><strong>PEP 366</strong></a> - 主模块显式相对导入</span></dt><dd><span class="yiyi-st" id="yiyi-72">PEP由Nick Coghlan编写和实施。</span></dd><dt><span class="yiyi-st" id="yiyi-73"><span class="target" id="index-8"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0451"><strong>PEP 451</strong></a> - 导入系统的ModuleSpec类型</span></dt><dd><span class="yiyi-st" id="yiyi-74">PEP由Eric Snow编写和实施</span></dd></dl><p><span class="yiyi-st" id="yiyi-75"><a class="reference internal" href="../using/cmdline.html#using-on-general"><span>Command line and environment</span></a> - CPython命令行详细信息</span></p><p class="last"><span class="yiyi-st" id="yiyi-76"><a class="reference internal" href="importlib.html#importlib.import_module" title="importlib.import_module"><code class="xref py py-func docutils literal"><span class="pre">importlib.import_module()</span></code></a>函数</span></p></div></div></div>