mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 06:55:36 +08:00
26 lines
40 KiB
HTML
26 lines
40 KiB
HTML
<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> 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中的最后一个项目> 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.SourceFileLoader(name,</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> |