2019-04-21 11:50:48 +08:00

26 lines
40 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-imp"><h1><span class="yiyi-st" id="yiyi-10">36.2. <a class="reference internal" href="#module-imp" title="imp: Access the implementation of the import statement. (deprecated)"><code class="xref py py-mod docutils literal"><span class="pre">imp</span></code></a> - 访问<a class="reference internal" href="../reference/import.html#importsystem"><span>import</span></a>内部</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/imp.py">Lib/imp.py</a></span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-12"><span class="versionmodified">自版本3.4后已弃用:</span> <a class="reference internal" href="#module-imp" title="imp: Access the implementation of the import statement. (deprecated)"><code class="xref py py-mod docutils literal"><span class="pre">imp</span></code></a>包正在等待废弃,换成<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></div><p><span class="yiyi-st" id="yiyi-13">此模块提供了用于实现<a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal"><span class="pre">import</span></code></a>语句的机制的接口。</span><span class="yiyi-st" id="yiyi-14">它定义了以下常量和函数:</span></p><dl class="function"><dt id="imp.get_magic"><span class="yiyi-st" id="yiyi-15"> <code class="descclassname">imp.</code><code class="descname">get_magic</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p id="index-1"><span class="yiyi-st" id="yiyi-16">返回用于识别字节编译代码文件(<code class="file docutils literal"><span class="pre">.pyc</span></code>文件)的魔术字符串值。</span><span class="yiyi-st" id="yiyi-17">每个Python版本的此值可能不同。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-18"><span class="versionmodified">自版本3.4后已弃用:</span>改用<a class="reference internal" href="importlib.html#importlib.util.MAGIC_NUMBER" title="importlib.util.MAGIC_NUMBER"><code class="xref py py-attr docutils literal"><span class="pre">importlib.util.MAGIC_NUMBER</span></code></a></span></p></div></dd></dl><dl class="function"><dt id="imp.get_suffixes"><span class="yiyi-st" id="yiyi-19"> <code class="descclassname">imp.</code><code class="descname">get_suffixes</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-20">返回一个3元素元组的列表每个元组描述特定类型的模块。</span><span class="yiyi-st" id="yiyi-21">每个三元组具有<code class="docutils literal"><span class="pre">(后缀,</span> <span class="pre">模式,</span> <span class="pre">类型)</span></code>的形式,其中<em>是要附加到模块名称以形成要搜索的文件名的字符串,<em>模式</em>是要传递到内建<a class="reference internal" href="functions.html#open" title="open"><code class="xref py py-func docutils literal"><span class="pre">open()</span></code></a>函数的模式字符串,文件(对于文本文件可以是<code class="docutils literal"><span class="pre">'r'</span></code>,对于二进制文件可以是<code class="docutils literal"><span class="pre">'rb'</span></code><em>类型</em>是文件类型,以下描述的值<a class="reference internal" href="#imp.PY_SOURCE" title="imp.PY_SOURCE"><code class="xref py py-const docutils literal"><span class="pre">PY_SOURCE</span></code></a><a class="reference internal" href="#imp.PY_COMPILED" title="imp.PY_COMPILED"><code class="xref py py-const docutils literal"><span class="pre">PY_COMPILED</span></code></a><a class="reference internal" href="#imp.C_EXTENSION" title="imp.C_EXTENSION"><code class="xref py py-const docutils literal"><span class="pre">C_EXTENSION</span></code></a>中的一个。</em></span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-22"><span class="versionmodified">自版本3.3后已弃用:</span>改用<a class="reference internal" href="importlib.html#module-importlib.machinery" title="importlib.machinery: Importers and path hooks"><code class="xref py py-mod docutils literal"><span class="pre">importlib.machinery</span></code></a>中定义的常量。</span></p></div></dd></dl><dl class="function"><dt id="imp.find_module"><span class="yiyi-st" id="yiyi-23"> <code class="descclassname">imp.</code><code class="descname">find_module</code><span class="sig-paren">(</span><em>name</em><span class="optional">[</span>, <em>path</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-24">尝试找到<em>名称</em></span><span class="yiyi-st" id="yiyi-25">如果省略<em>path</em><code class="docutils literal"><span class="pre">None</span></code>,将搜索由<code class="docutils literal"><span class="pre">sys.path</span></code>给出的目录名称列表,但首先搜索几个特殊位置:该函数尝试查找具有给定名称(<a class="reference internal" href="#imp.C_BUILTIN" title="imp.C_BUILTIN"><code class="xref py py-const docutils literal"><span class="pre">C_BUILTIN</span></code></a>),冻结模块(<a class="reference internal" href="#imp.PY_FROZEN" title="imp.PY_FROZEN"><code class="xref py py-const docutils literal"><span class="pre">PY_FROZEN</span></code></a>的内建模块在某些系统上一些其他地方被查找在Windows上它注册表中可能指向一个特定的文件</span></p><p><span class="yiyi-st" id="yiyi-26">否则,<em>路径</em>必须是目录名称列表;将搜索每个目录中具有由上述<a class="reference internal" href="#imp.get_suffixes" title="imp.get_suffixes"><code class="xref py py-func docutils literal"><span class="pre">get_suffixes()</span></code></a>返回的任何后缀的文件。</span><span class="yiyi-st" id="yiyi-27">列表中无效的名称将被忽略(但所有列表项必须是字符串)。</span></p><p><span class="yiyi-st" id="yiyi-28">如果搜索成功返回值为3元素元组<code class="docutils literal"><span class="pre">(文件,</span> <span class="pre">路径名,</span> <span class="pre">描述)</span> </code></span></p><p><span class="yiyi-st" id="yiyi-29"><em>文件</em>是位于开头的开放<a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">file object</span></a><em>路径名</em>是找到的文件的路径名,<em>描述</em>是由<a class="reference internal" href="#imp.get_suffixes" title="imp.get_suffixes"><code class="xref py py-func docutils literal"><span class="pre">get_suffixes()</span></code></a>返回的列表中包含的描述所找到的模块类型的3元素元组。</span></p><p><span class="yiyi-st" id="yiyi-30">如果模块不在文件中,返回的<em>文件</em><code class="docutils literal"><span class="pre">None</span></code><em>路径名</em>为空字符串,<em>/ t4&gt; tuple包含其后缀和模式的空字符串模块类型如上面括号中所示。</em></span><span class="yiyi-st" id="yiyi-31">如果搜索不成功,则会引发<a class="reference internal" href="exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal"><span class="pre">ImportError</span></code></a></span><span class="yiyi-st" id="yiyi-32">其他异常表示参数或环境的问题。</span></p><p><span class="yiyi-st" id="yiyi-33">如果模块是包,<em>文件</em><code class="docutils literal"><span class="pre">None</span></code><em>路径名</em>是包路径和<em>描述 t4中的最后一个项目&gt; tuple是<a class="reference internal" href="#imp.PKG_DIRECTORY" title="imp.PKG_DIRECTORY"><code class="xref py py-const docutils literal"><span class="pre">PKG_DIRECTORY</span></code></a></em></span></p><p><span class="yiyi-st" id="yiyi-34">此函数不处理分层模块名称(包含点的名称)。</span><span class="yiyi-st" id="yiyi-35">为了找到<em>PM</em>,即包裹<em>P</em>的子模块<em>M</em>,请使用<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">find_module()</span></code></a><a class="reference internal" href="#imp.load_module" title="imp.load_module"><code class="xref py py-func docutils literal"><span class="pre">load_module()</span></code></a>找到并加载包<em>P</em>,然后使用<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">find_module()</span></code></a>,将<em>路径</em>参数设置为<code class="docutils literal"><span class="pre">P.__path__</span></code></span><span class="yiyi-st" id="yiyi-36"><em>P</em>本身有点名时,以递归方式应用此配方。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-37"><span class="versionmodified">自版本3.3后已弃用:</span>除非需要Python 3.3兼容性,否则使用<a class="reference internal" href="importlib.html#importlib.util.find_spec" title="importlib.util.find_spec"><code class="xref py py-func docutils literal"><span class="pre">importlib.util.find_spec()</span></code></a>,在这种情况下,请使用<a class="reference internal" href="importlib.html#importlib.find_loader" title="importlib.find_loader"><code class="xref py py-func docutils literal"><span class="pre">importlib.find_loader()</span></code></a></span></p></div></dd></dl><dl class="function"><dt id="imp.load_module"><span class="yiyi-st" id="yiyi-38"> <code class="descclassname">imp.</code><code class="descname">load_module</code><span class="sig-paren">(</span><em>name</em>, <em>file</em>, <em>pathname</em>, <em>description</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-39">加载以前由<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">find_module()</span></code></a>发现的模块(或通过其他方式进行的搜索,产生兼容的结果)。</span><span class="yiyi-st" id="yiyi-40">此函数不仅仅导入模块:如果模块已经导入,它将重新加载模块!</span><span class="yiyi-st" id="yiyi-41"><em>name</em>参数指示完整的模块名称(包括程序包名称,如果它是程序包的子模块)。</span><span class="yiyi-st" id="yiyi-42"><em>文件</em>参数是打开的文件,<em>路径名</em>是相应的文件名;当模块是包或者没有从文件加载时,这些可以分别是<code class="docutils literal"><span class="pre">None</span></code><code class="docutils literal"><span class="pre">''</span></code></span><span class="yiyi-st" id="yiyi-43"><em>描述</em>参数是一个元组,由<a class="reference internal" href="#imp.get_suffixes" title="imp.get_suffixes"><code class="xref py py-func docutils literal"><span class="pre">get_suffixes()</span></code></a>返回,描述必须加载什么样的模块。</span></p><p><span class="yiyi-st" id="yiyi-44">如果加载成功,返回值是模块对象;否则,引发异常(通常<a class="reference internal" href="exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal"><span class="pre">ImportError</span></code></a>)。</span></p><p><span class="yiyi-st" id="yiyi-45"><strong>重要提示:</strong>如果不是<code class="docutils literal"><span class="pre">None</span></code>,即使发生异常,调用者也负责关闭<em>文件</em>参数。</span><span class="yiyi-st" id="yiyi-46">最好使用<a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> ... <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a>语句。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-47"><span class="versionmodified">从版本3.3开始弃用:</span>如果之前与<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">imp.find_module()</span></code></a>结合使用,则考虑使用<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>,否则使用加载器由您为<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">imp.find_module()</span></code></a>选择的替换返回。</span><span class="yiyi-st" id="yiyi-48">如果您直接调用<a class="reference internal" href="#imp.load_module" title="imp.load_module"><code class="xref py py-func docutils literal"><span class="pre">imp.load_module()</span></code></a>和相关函数,请使用<a class="reference internal" href="importlib.html#module-importlib.machinery" title="importlib.machinery: Importers and path hooks"><code class="xref py py-mod docutils literal"><span class="pre">importlib.machinery</span></code></a>中的类,例如</span><span class="yiyi-st" id="yiyi-49"><code class="docutils literal"><span class="pre">importlib.machinery.SourceFileLoadername</span> <span class="pre">path.load_module()</span></code></span></p></div></dd></dl><dl class="function"><dt id="imp.new_module"><span class="yiyi-st" id="yiyi-50"> <code class="descclassname">imp.</code><code class="descname">new_module</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-51">返回一个名为<em>name</em>的新模块对象。</span><span class="yiyi-st" id="yiyi-52">此对象<em>不是</em>插入到<code class="docutils literal"><span class="pre">sys.modules</span></code>中。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-53"><span class="versionmodified">自版本3.4后已弃用:</span>改用<a class="reference internal" href="types.html#types.ModuleType" title="types.ModuleType"><code class="xref py py-class docutils literal"><span class="pre">types.ModuleType</span></code></a></span></p></div></dd></dl><dl class="function"><dt id="imp.reload"><span class="yiyi-st" id="yiyi-54"> <code class="descclassname">imp.</code><code class="descname">reload</code><span class="sig-paren">(</span><em>module</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-55">重新载入先前导入的<em>模块</em></span><span class="yiyi-st" id="yiyi-56">参数必须是一个模块对象,因此必须先被成功导入。</span><span class="yiyi-st" id="yiyi-57">如果您已使用外部编辑器编辑了模块源文件并希望在不离开Python解释器的情况下尝试新版本这将非常有用。</span><span class="yiyi-st" id="yiyi-58">返回值是模块对象(与<em>模块</em>参数相同)。</span></p><p><span class="yiyi-st" id="yiyi-59">当执行<code class="docutils literal"><span class="pre">reload(module)</span></code>时:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-60">Python模块的代码被重新编译并重新执行模块级代码定义一组新的对象这些对象绑定到模块字典中的名称。</span><span class="yiyi-st" id="yiyi-61">扩展模块的<code class="docutils literal"><span class="pre">init</span></code>功能不再第二次调用。</span></li><li><span class="yiyi-st" id="yiyi-62">与Python中的所有其他对象一样旧对象只有在引用计数下降到零后才被回收。</span></li><li><span class="yiyi-st" id="yiyi-63">模块命名空间中的名称将更新为指向任何新的或已更改的对象。</span></li><li><span class="yiyi-st" id="yiyi-64">对旧对象的其他引用(例如模块外部的名称)不会重新引用来引用新对象,如果需要,必须在每个命名空间中对其进行更新。</span></li></ul><p><span class="yiyi-st" id="yiyi-65">还有一些其他警告:</span></p><p><span class="yiyi-st" id="yiyi-66">重新加载模块时,将保留其字典(包含模块的全局变量)。</span><span class="yiyi-st" id="yiyi-67">名称的重定义将覆盖旧的定义,因此这通常不是问题。</span><span class="yiyi-st" id="yiyi-68">如果模块的新版本未定义由旧版本定义的名称,则旧定义将保留。</span><span class="yiyi-st" id="yiyi-69">如果它维护一个全局表或对象缓存,使用<a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a>语句可以测试表的存在并跳过其初始化,如果需要,这个特性可以用于模块的优势:</span></p><pre><code class="language-python"><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">cache</span>
<span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
<span class="n">cache</span> <span class="o">=</span> <span class="p">{}</span>
</code></pre><p><span class="yiyi-st" id="yiyi-70">除了<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><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><a class="reference internal" href="builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal"><span class="pre">builtins</span></code></a>除外,重新加载内建或动态加载的模块通常不太有用。</span><span class="yiyi-st" id="yiyi-71">然而,在许多情况下,扩展模块不被设计为被不止一次地初始化,并且可以在被重新加载时以任意方式失败。</span></p><p><span class="yiyi-st" id="yiyi-72">如果模块使用<a class="reference internal" href="../reference/simple_stmts.html#from"><code class="xref std std-keyword docutils literal"><span class="pre">from</span></code></a> ... <a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal"><span class="pre">import</span></code></a> ...从另一个模块导入对象,则对其他模块调用<a class="reference internal" href="#imp.reload" title="imp.reload"><code class="xref py py-func docutils literal"><span class="pre">reload()</span></code></a>其中一个方法是重新执行<a class="reference internal" href="../reference/simple_stmts.html#from"><code class="xref std std-keyword docutils literal"><span class="pre">from</span></code></a>语句,另一个是使用<a class="reference internal" href="../reference/simple_stmts.html#import"><code class="xref std std-keyword docutils literal"><span class="pre">import</span></code></a>和限定名称(<em>module</em></span><span class="yiyi-st" id="yiyi-73">* name *)。</span></p><p><span class="yiyi-st" id="yiyi-74">如果一个模块实例化一个类的实例,重新加载定义该类的模块不会影响实例的方法定义 - 它们继续使用旧的类定义。</span><span class="yiyi-st" id="yiyi-75">对于派生类同样如此。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-76"><span class="versionmodified">在版本3.3中更改:</span>依赖于正在重新加载的模块上定义的<code class="docutils literal"><span class="pre">__name__</span></code><code class="docutils literal"><span class="pre">__loader__</span></code>,而不仅仅是<code class="docutils literal"><span class="pre">__name__</span></code></span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-77"><span class="versionmodified">自版本3.4后已弃用:</span>改用<a class="reference internal" href="importlib.html#importlib.reload" title="importlib.reload"><code class="xref py py-func docutils literal"><span class="pre">importlib.reload()</span></code></a></span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-78">以下函数是处理<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 class="versionadded"><p><span class="yiyi-st" id="yiyi-79"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div><dl class="function"><dt id="imp.cache_from_source"><span class="yiyi-st" id="yiyi-80"> <code class="descclassname">imp.</code><code class="descname">cache_from_source</code><span class="sig-paren">(</span><em>path</em>, <em>debug_override=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-81"><span class="target" id="index-3"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a>路径返回到与源<em>路径</em>相关联的字节编译文件。</span><span class="yiyi-st" id="yiyi-82">例如,如果<em>path</em><code class="docutils literal"><span class="pre">/foo/bar/baz.py</span></code>,则返回值为<code class="docutils literal"><span class="pre">/foo/bar/__pycache__/baz.cpython-32.pyc</span></code> for Python 3.2。</span><span class="yiyi-st" id="yiyi-83"><code class="docutils literal"><span class="pre">cpython-32</span></code>字符串来自当前的魔术标签(参见<a class="reference internal" href="#imp.get_tag" title="imp.get_tag"><code class="xref py py-func docutils literal"><span class="pre">get_tag()</span></code></a>;如果没有定义<code class="xref py py-attr docutils literal"><span class="pre">sys.implementation.cache_tag</span></code>,则<a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal"><span class="pre">NotImplementedError</span></code></a>会被提出)。</span><span class="yiyi-st" id="yiyi-84">通过为<em>debug_override</em>传递<code class="docutils literal"><span class="pre">True</span></code><code class="docutils literal"><span class="pre">False</span></code>,您可以覆盖<code class="docutils literal"><span class="pre">__debug__</span></code>的系统值,从而导致优化的字节码。</span></p><p><span class="yiyi-st" id="yiyi-85"><em>路径</em>不需要存在。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-86"><span class="versionmodified">在版本3.3中已更改:</span>如果<code class="xref py py-attr docutils literal"><span class="pre">sys.implementation.cache_tag</span></code><code class="docutils literal"><span class="pre">None</span></code>,则会引发<a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal"><span class="pre">NotImplementedError</span></code></a></span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-87"><span class="versionmodified">自版本3.4后已弃用:</span>改用<a class="reference internal" href="importlib.html#importlib.util.cache_from_source" title="importlib.util.cache_from_source"><code class="xref py py-func docutils literal"><span class="pre">importlib.util.cache_from_source()</span></code></a></span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-88"><span class="versionmodified">在版本3.5中已更改:</span> <em>debug_override</em>参数不再创建<code class="docutils literal"><span class="pre">.pyo</span></code>文件。</span></p></div></dd></dl><dl class="function"><dt id="imp.source_from_cache"><span class="yiyi-st" id="yiyi-89"> <code class="descclassname">imp.</code><code class="descname">source_from_cache</code><span class="sig-paren">(</span><em>path</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-90">给定<em>路径</em><span class="target" id="index-4"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a>文件名,返回关联的源代码文件路径。</span><span class="yiyi-st" id="yiyi-91">例如,如果<em>路径</em><code class="docutils literal"><span class="pre">/foo/bar/__pycache__/baz.cpython-32.pyc</span></code>,则返回的路径为<code class="docutils literal"><span class="pre">/foo/bar/baz.py</span></code></span><span class="yiyi-st" id="yiyi-92"><em>path</em>不需要存在,但如果它不符合<span class="target" id="index-5"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a>格式,则会引发<code class="docutils literal"><span class="pre">ValueError</span></code></span><span class="yiyi-st" id="yiyi-93">如果未定义<code class="xref py py-attr docutils literal"><span class="pre">sys.implementation.cache_tag</span></code>,则会引发<a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal"><span class="pre">NotImplementedError</span></code></a></span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-94"><span class="versionmodified">在未定义<code class="xref py py-attr docutils literal"><span class="pre">sys.implementation.cache_tag</span></code>在版本3.3中更改了</span>提升<a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal"><span class="pre">NotImplementedError</span></code></a></span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-95"><span class="versionmodified">自从版本3.4开始弃用:</span>改为使用<a class="reference internal" href="importlib.html#importlib.util.source_from_cache" title="importlib.util.source_from_cache"><code class="xref py py-func docutils literal"><span class="pre">importlib.util.source_from_cache()</span></code></a></span></p></div></dd></dl><dl class="function"><dt id="imp.get_tag"><span class="yiyi-st" id="yiyi-96"> <code class="descclassname">imp.</code><code class="descname">get_tag</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-97">返回与<a class="reference internal" href="#imp.get_magic" title="imp.get_magic"><code class="xref py py-func docutils literal"><span class="pre">get_magic()</span></code></a>返回的Python的幻数的版本匹配的<span class="target" id="index-6"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a>魔术标记字符串。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-98"><span class="versionmodified">自版本3.4后弃用:</span>直接从Python 3.3开始使用<code class="xref py py-attr docutils literal"><span class="pre">sys.implementation.cache_tag</span></code></span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-99">以下功能有助于与导入系统的内部锁定机制交互。</span><span class="yiyi-st" id="yiyi-100">导入的锁定语义是一个实现细节,它可能因版本而异。</span><span class="yiyi-st" id="yiyi-101">然而Python确保循环导入工作没有任何死锁。</span></p><dl class="function"><dt id="imp.lock_held"><span class="yiyi-st" id="yiyi-102"> <code class="descclassname">imp.</code><code class="descname">lock_held</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-103">如果全局导入锁定当前持有,则返回<code class="docutils literal"><span class="pre">True</span></code>,否则<code class="docutils literal"><span class="pre">False</span></code></span><span class="yiyi-st" id="yiyi-104">在没有线程的平台上,始终返回<code class="docutils literal"><span class="pre">False</span></code></span></p><p><span class="yiyi-st" id="yiyi-105">在具有线程的平台上,执行导入的线程首先保存全局导入锁定,然后为其余导入设置每个模块的锁定。</span><span class="yiyi-st" id="yiyi-106">这阻止其他线程导入同一个模块,直到原始导入完成,从而阻止其他线程看到由原始线程构造的不完整的模块对象。</span><span class="yiyi-st" id="yiyi-107">循环导入是一个例外,通过构造,它必须在某个时间暴露一个不完整的模块对象。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-108"><span class="versionmodified">在版本3.3中更改:</span>大部分锁定方案已更改为按模块锁定。</span><span class="yiyi-st" id="yiyi-109">为一些关键任务保留全局导入锁,例如初始化每个模块的锁。</span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-110"><span class="versionmodified">自3.4版起已弃用。</span></span></p></div></dd></dl><dl class="function"><dt id="imp.acquire_lock"><span class="yiyi-st" id="yiyi-111"> <code class="descclassname">imp.</code><code class="descname">acquire_lock</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-112">获取当前线程的解释器的全局导入锁。</span><span class="yiyi-st" id="yiyi-113">导入挂钩时应使用此锁定以确保导入模块时的线程安全。</span></p><p><span class="yiyi-st" id="yiyi-114">一旦线程获取了导入锁,同一线程可以再次获取它而不阻塞;线程必须每次释放它一次它已经获得它。</span></p><p><span class="yiyi-st" id="yiyi-115">在没有线程的平台上,此函数不执行任何操作。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-116"><span class="versionmodified">在版本3.3中更改:</span>大部分锁定方案已更改为按模块锁定。</span><span class="yiyi-st" id="yiyi-117">为一些关键任务保留全局导入锁,例如初始化每个模块的锁。</span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-118"><span class="versionmodified">自3.4版起已弃用。</span></span></p></div></dd></dl><dl class="function"><dt id="imp.release_lock"><span class="yiyi-st" id="yiyi-119"> <code class="descclassname">imp.</code><code class="descname">release_lock</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-120">释放解释器的全局导入锁定。</span><span class="yiyi-st" id="yiyi-121">在没有线程的平台上,此函数不执行任何操作。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-122"><span class="versionmodified">在版本3.3中更改:</span>大部分锁定方案已更改为按模块锁定。</span><span class="yiyi-st" id="yiyi-123">为一些关键任务保留全局导入锁,例如初始化每个模块的锁。</span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-124"><span class="versionmodified">自3.4版起已弃用。</span></span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-125">在此模块中定义的以下具有整数值的常量用于指示<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">find_module()</span></code></a>的搜索结果。</span></p><dl class="data"><dt id="imp.PY_SOURCE"><span class="yiyi-st" id="yiyi-126"> <code class="descclassname">imp.</code><code class="descname">PY_SOURCE</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-127">找到该模块作为源文件。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-128"><span class="versionmodified">自版本3.3起已弃用。</span></span></p></div></dd></dl><dl class="data"><dt id="imp.PY_COMPILED"><span class="yiyi-st" id="yiyi-129"> <code class="descclassname">imp.</code><code class="descname">PY_COMPILED</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-130">该模块被找到为编译代码对象文件。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-131"><span class="versionmodified">自版本3.3起已弃用。</span></span></p></div></dd></dl><dl class="data"><dt id="imp.C_EXTENSION"><span class="yiyi-st" id="yiyi-132"> <code class="descclassname">imp.</code><code class="descname">C_EXTENSION</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-133">该模块被找到为可动态加载的共享库。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-134"><span class="versionmodified">自版本3.3起已弃用。</span></span></p></div></dd></dl><dl class="data"><dt id="imp.PKG_DIRECTORY"><span class="yiyi-st" id="yiyi-135"> <code class="descclassname">imp.</code><code class="descname">PKG_DIRECTORY</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-136">该模块被找到作为包目录。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-137"><span class="versionmodified">自版本3.3起已弃用。</span></span></p></div></dd></dl><dl class="data"><dt id="imp.C_BUILTIN"><span class="yiyi-st" id="yiyi-138"> <code class="descclassname">imp.</code><code class="descname">C_BUILTIN</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-139">该模块被找到作为内建模块。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-140"><span class="versionmodified">自版本3.3起已弃用。</span></span></p></div></dd></dl><dl class="data"><dt id="imp.PY_FROZEN"><span class="yiyi-st" id="yiyi-141"> <code class="descclassname">imp.</code><code class="descname">PY_FROZEN</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-142">该模块被发现为冻结模块。</span></p><div class="deprecated"><p><span class="yiyi-st" id="yiyi-143"><span class="versionmodified">自版本3.3起已弃用。</span></span></p></div></dd></dl><dl class="class"><dt id="imp.NullImporter"><span class="yiyi-st" id="yiyi-144"> <em class="property">class </em><code class="descclassname">imp.</code><code class="descname">NullImporter</code><span class="sig-paren">(</span><em>path_string</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-145"><a class="reference internal" href="#imp.NullImporter" title="imp.NullImporter"><code class="xref py py-class docutils literal"><span class="pre">NullImporter</span></code></a>类型是通过未找到任何模块处理非目录路径字符串的<span class="target" id="index-7"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0302"><strong>PEP 302</strong></a>导入钩子。</span><span class="yiyi-st" id="yiyi-146">使用现有目录或空字符串调用此类型引发<a class="reference internal" href="exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal"><span class="pre">ImportError</span></code></a></span><span class="yiyi-st" id="yiyi-147">否则,将返回<a class="reference internal" href="#imp.NullImporter" title="imp.NullImporter"><code class="xref py py-class docutils literal"><span class="pre">NullImporter</span></code></a>实例。</span></p><p><span class="yiyi-st" id="yiyi-148">实例只有一个方法:</span></p><dl class="method"><dt id="imp.NullImporter.find_module"><span class="yiyi-st" id="yiyi-149"> <code class="descname">find_module</code><span class="sig-paren">(</span><em>fullname</em><span class="optional">[</span>, <em>path</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-150">此方法始终返回<code class="docutils literal"><span class="pre">None</span></code>,表示找不到请求的模块。</span></p></dd></dl><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-151"><span class="versionmodified">在版本3.3中更改:</span> <code class="docutils literal"><span class="pre">None</span></code>已插入到<code class="docutils literal"><span class="pre">sys.path_importer_cache</span></code>中,而不是<a class="reference internal" href="#imp.NullImporter" title="imp.NullImporter"><code class="xref py py-class docutils literal"><span class="pre">NullImporter</span></code></a>的实例。</span></p></div><div class="deprecated"><p><span class="yiyi-st" id="yiyi-152"><span class="versionmodified">自版本3.4后弃用:</span>改为将<code class="docutils literal"><span class="pre">None</span></code>插入<code class="docutils literal"><span class="pre">sys.path_importer_cache</span></code></span></p></div></dd></dl><div class="section" id="examples"><h2><span class="yiyi-st" id="yiyi-153">36.2.1. </span><span class="yiyi-st" id="yiyi-154">实例</span></h2><p><span class="yiyi-st" id="yiyi-155">以下函数模拟了直到Python 1.4的标准import语句没有分层模块名称</span><span class="yiyi-st" id="yiyi-156">(由于<a class="reference internal" href="#imp.find_module" title="imp.find_module"><code class="xref py py-func docutils literal"><span class="pre">find_module()</span></code></a>已经扩展并且在1.4中添加了<a class="reference internal" href="#imp.load_module" title="imp.load_module"><code class="xref py py-func docutils literal"><span class="pre">load_module()</span></code></a>,因此此<em>实现</em></span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">imp</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="k">def</span> <span class="nf">__import__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">globals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">locals</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">fromlist</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="c1"># Fast path: see if the module has already been imported.</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="c1"># If any of the following calls raises an exception,</span>
<span class="c1"># there's a problem we can't handle -- let the caller handle it.</span>
<span class="n">fp</span><span class="p">,</span> <span class="n">pathname</span><span class="p">,</span> <span class="n">description</span> <span class="o">=</span> <span class="n">imp</span><span class="o">.</span><span class="n">find_module</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">imp</span><span class="o">.</span><span class="n">load_module</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">fp</span><span class="p">,</span> <span class="n">pathname</span><span class="p">,</span> <span class="n">description</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="c1"># Since we may exit via an exception, close fp explicitly.</span>
<span class="k">if</span> <span class="n">fp</span><span class="p">:</span>
<span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div></div></div>