mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
21 lines
21 KiB
HTML
21 lines
21 KiB
HTML
<div class="body" role="main"><div class="section" id="module-zipapp"><h1><span class="yiyi-st" id="yiyi-10">28.4. <a class="reference internal" href="#module-zipapp" title="zipapp: Manage executable python zip archives"><code class="xref py py-mod docutils literal"><span class="pre">zipapp</span></code></a> - 管理可执行文件python zip档案</span></h1><div class="versionadded"><p><span class="yiyi-st" id="yiyi-11"><span class="versionmodified">版本3.5中的新功能。</span></span></p></div><p><span class="yiyi-st" id="yiyi-12"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/zipapp.py">Lib / zipapp.py</a></span></p><p><span class="yiyi-st" id="yiyi-13">此模块提供的工具可用于管理包含Python代码的zip文件的创建,这种zip文件可<a class="reference internal" href="../using/cmdline.html#using-on-interface-options"><span>直接被Python解释器执行</span></a>。</span><span class="yiyi-st" id="yiyi-14">该模块提供<a class="reference internal" href="#zipapp-command-line-interface"><span>命令行界面</span></a>和<a class="reference internal" href="#zipapp-python-api"><span>Python API</span></a>。</span></p><div class="section" id="basic-example"><h2><span class="yiyi-st" id="yiyi-15">28.4.1. </span><span class="yiyi-st" id="yiyi-16">Basic Example</span></h2><p><span class="yiyi-st" id="yiyi-17">以下示例说明如何从包含Python代码的目录使用<a class="reference internal" href="#zipapp-command-line-interface"><span>命令行界面</span></a>创建可执行文件。</span><span class="yiyi-st" id="yiyi-18">When run, the archive will execute the <code class="docutils literal"><span class="pre">main</span></code> function from the module <code class="docutils literal"><span class="pre">myapp</span></code> in the archive.</span></p><div class="highlight-sh"><div class="highlight"><pre><span></span>$ python -m zipapp myapp -m <span class="s2">"myapp:main"</span>
|
||
$ python myapp.pyz
|
||
<output from myapp>
|
||
</pre></div></div></div><div class="section" id="command-line-interface"><h2><span class="yiyi-st" id="yiyi-19">28.4.2. </span><span class="yiyi-st" id="yiyi-20">Command-Line Interface</span></h2><p><span class="yiyi-st" id="yiyi-21">当从命令行调用为程序时,使用以下形式:</span></p><div class="highlight-sh"><div class="highlight"><pre><span></span>$ python -m zipapp <span class="nb">source</span> <span class="o">[</span>options<span class="o">]</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-22">如果<em>source</em>是目录,则将从<em>源</em>的内容创建归档。</span><span class="yiyi-st" id="yiyi-23">如果<em>source</em>是一个文件,它应该是一个存档,并且它将被复制到目标存档(或者如果指定了-info选项,则将显示其shebang行的内容)。</span></p><p><span class="yiyi-st" id="yiyi-24">以下选项被理解:</span></p><dl class="cmdoption"><dt id="cmdoption-zipapp-o"><span class="yiyi-st" id="yiyi-25"> <span id="cmdoption-zipapp--output"></span><code class="descname">-o</code><code class="descclassname"> <output></code><code class="descclassname">, </code><code class="descname">--output</code><code class="descclassname">=<output></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-26">将输出写入名为<em>输出</em>的文件。</span><span class="yiyi-st" id="yiyi-27">如果未指定此选项,则输出文件名将与输入<em>源</em>相同,并添加了扩展名<code class="docutils literal"><span class="pre">.pyz</span></code>。</span><span class="yiyi-st" id="yiyi-28">如果给定了显式文件名,则按原样使用(因此,如果需要,应包括<code class="docutils literal"><span class="pre">.pyz</span></code>扩展名)。</span></p><p><span class="yiyi-st" id="yiyi-29">如果<em>源</em>是存档(在这种情况下,<em>输出</em>不能与<em>源</em>相同),则必须指定输出文件名。</span></p></dd></dl><dl class="cmdoption"><dt id="cmdoption-zipapp-p"><span class="yiyi-st" id="yiyi-30"> <span id="cmdoption-zipapp--python"></span><code class="descname">-p</code><code class="descclassname"> <interpreter></code><code class="descclassname">, </code><code class="descname">--python</code><code class="descclassname">=<interpreter></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-31">添加<code class="docutils literal"><span class="pre">#!</span></code></span><span class="yiyi-st" id="yiyi-32">行到指定<em>解释器</em>的档案作为要运行的命令。</span><span class="yiyi-st" id="yiyi-33">此外,在POSIX上,使归档可执行。</span><span class="yiyi-st" id="yiyi-34">默认值为不写<code class="docutils literal"><span class="pre">#!</span></code></span><span class="yiyi-st" id="yiyi-35">行,并且不使文件可执行。</span></p></dd></dl><dl class="cmdoption"><dt id="cmdoption-zipapp-m"><span class="yiyi-st" id="yiyi-36"> <span id="cmdoption-zipapp--main"></span><code class="descname">-m</code><code class="descclassname"> <mainfn></code><code class="descclassname">, </code><code class="descname">--main</code><code class="descclassname">=<mainfn></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-37">将<code class="docutils literal"><span class="pre">__main__.py</span></code>文件写入执行<em>mainfn</em>的存档。</span><span class="yiyi-st" id="yiyi-38"><em>mainfn</em>参数的格式应为“pkg.mod:fn”,其中“pkg.mod”是存档中的包/模块,“fn”是给定模块中的可调用。</span><span class="yiyi-st" id="yiyi-39"><code class="docutils literal"><span class="pre">__main__.py</span></code>文件将执行该可调用。</span></p><p><span class="yiyi-st" id="yiyi-40">复制存档时无法指定<a class="reference internal" href="#cmdoption-zipapp--main"><code class="xref std std-option docutils literal"><span class="pre">--main</span></code></a>。</span></p></dd></dl><dl class="cmdoption"><dt id="cmdoption-zipapp--info"><span class="yiyi-st" id="yiyi-41"> <code class="descname">--info</code><code class="descclassname"></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-42">显示嵌入在归档中的解释器,用于诊断目的。</span><span class="yiyi-st" id="yiyi-43">在这种情况下,将忽略任何其他选项,SOURCE必须是存档,而不是目录。</span></p></dd></dl><dl class="cmdoption"><dt id="cmdoption-zipapp-h"><span class="yiyi-st" id="yiyi-44"> <span id="cmdoption-zipapp--help"></span><code class="descname">-h</code><code class="descclassname"></code><code class="descclassname">, </code><code class="descname">--help</code><code class="descclassname"></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-45">打印简短的使用消息并退出。</span></p></dd></dl></div><div class="section" id="python-api"><h2><span class="yiyi-st" id="yiyi-46">28.4.3. </span><span class="yiyi-st" id="yiyi-47">Python API</span></h2><p><span class="yiyi-st" id="yiyi-48">模块定义了两个方便的功能:</span></p><dl class="function"><dt id="zipapp.create_archive"><span class="yiyi-st" id="yiyi-49"> <code class="descclassname">zipapp.</code><code class="descname">create_archive</code><span class="sig-paren">(</span><em>source</em>, <em>target=None</em>, <em>interpreter=None</em>, <em>main=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-50">从<em>源</em>创建应用程序归档。</span><span class="yiyi-st" id="yiyi-51">源可以是以下任何一种:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-52">目录的名称或指向目录的<a class="reference internal" href="pathlib.html#pathlib.Path" title="pathlib.Path"><code class="xref py py-class docutils literal"><span class="pre">pathlib.Path</span></code></a>对象,在这种情况下,将从该目录的内容创建新的应用程序归档。</span></li><li><span class="yiyi-st" id="yiyi-53">现有应用程序归档文件的名称或引用此类文件的<a class="reference internal" href="pathlib.html#pathlib.Path" title="pathlib.Path"><code class="xref py py-class docutils literal"><span class="pre">pathlib.Path</span></code></a>对象,在这种情况下,将文件复制到目标(修改它以反映为<em>>解释器</em>参数)。</span><span class="yiyi-st" id="yiyi-54">如果需要,文件名应包含<code class="docutils literal"><span class="pre">.pyz</span></code>扩展名。</span></li><li><span class="yiyi-st" id="yiyi-55">以字节模式读取的文件对象。</span><span class="yiyi-st" id="yiyi-56">文件的内容应该是应用程序归档,并且文件对象假定位于归档的开始。</span></li></ul><p><span class="yiyi-st" id="yiyi-57"><em>目标</em>参数确定将写入结果归档的位置:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-58">如果它是文件的名称或<code class="xref py py-class docutils literal"><span class="pre">pathlb.Path</span></code>对象,则归档将写入该文件。</span></li><li><span class="yiyi-st" id="yiyi-59">如果它是一个打开的文件对象,则归档将被写入该文件对象,该对象必须打开以便以字节模式写入。</span></li><li><span class="yiyi-st" id="yiyi-60">如果省略目标(或无),则源必须是目录,目标将是与源相同名称的文件,并添加了<code class="docutils literal"><span class="pre">.pyz</span></code>扩展名。</span></li></ul><p><span class="yiyi-st" id="yiyi-61"><em>解释器</em>参数指定将要执行归档的Python解释器的名称。</span><span class="yiyi-st" id="yiyi-62">它在归档开始时写为“shebang”行。</span><span class="yiyi-st" id="yiyi-63">在POSIX上,这将被操作系统解释,在Windows上它将由Python启动程序处理。</span><span class="yiyi-st" id="yiyi-64">省略<em>解释器</em>会导致没有写入shebang行。</span><span class="yiyi-st" id="yiyi-65">如果指定了解释器,并且目标是文件名,则将设置目标文件的可执行位。</span></p><p><span class="yiyi-st" id="yiyi-66"><em>main</em>参数指定将用作归档的主程序的可调用的名称。</span><span class="yiyi-st" id="yiyi-67">它只能在源是目录且源尚未包含<code class="docutils literal"><span class="pre">__main__.py</span></code>文件时才能指定。</span><span class="yiyi-st" id="yiyi-68"><em>main</em>参数应采用“pkg.module:callable”的形式,并且通过导入“pkg.module”并执行没有参数的给定callable来运行归档。</span><span class="yiyi-st" id="yiyi-69">如果源是目录并且不包含<code class="docutils literal"><span class="pre">__main__.py</span></code>文件,则省略<em>main</em>是错误,否则生成的归档将不可执行。</span></p><p><span class="yiyi-st" id="yiyi-70">如果为<em>source</em>或<em>target</em>指定了文件对象,则调用create_archive后,调用者应负责关闭它。</span></p><p><span class="yiyi-st" id="yiyi-71">复制现有存档时,提供的文件对象只需要<code class="docutils literal"><span class="pre">read</span></code>和<code class="docutils literal"><span class="pre">readline</span></code>或<code class="docutils literal"><span class="pre">write</span></code>方法。</span><span class="yiyi-st" id="yiyi-72">从目录创建归档时,如果目标是文件对象,则它将传递到<code class="docutils literal"><span class="pre">zipfile.ZipFile</span></code>类,并且必须提供该类所需的方法。</span></p></dd></dl><dl class="function"><dt id="zipapp.get_interpreter"><span class="yiyi-st" id="yiyi-73"> <code class="descclassname">zipapp.</code><code class="descname">get_interpreter</code><span class="sig-paren">(</span><em>archive</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-74">返回<code class="docutils literal"><span class="pre">#!</span></code>中指定的解释器</span><span class="yiyi-st" id="yiyi-75">行在归档的开始。</span><span class="yiyi-st" id="yiyi-76">如果没有<code class="docutils literal"><span class="pre">#!</span></code></span><span class="yiyi-st" id="yiyi-77">行,返回<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><span class="yiyi-st" id="yiyi-78"><em>archive</em>参数可以是以字节模式读取的文件名或类文件对象。</span><span class="yiyi-st" id="yiyi-79">它假定在归档的开始。</span></p></dd></dl></div><div class="section" id="examples"><h2><span class="yiyi-st" id="yiyi-80">28.4.4. </span><span class="yiyi-st" id="yiyi-81">Examples</span></h2><p><span class="yiyi-st" id="yiyi-82">将目录封装到归档中,并运行它。</span></p><div class="highlight-sh"><div class="highlight"><pre><span></span>$ python -m zipapp myapp
|
||
$ python myapp.pyz
|
||
<output from myapp>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-83">同样可以使用<a class="reference internal" href="#zipapp.create_archive" title="zipapp.create_archive"><code class="xref py py-func docutils literal"><span class="pre">create_archive()</span></code></a> functon:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">zipapp</span>
|
||
<span class="gp">>>> </span><span class="n">zipapp</span><span class="o">.</span><span class="n">create_archive</span><span class="p">(</span><span class="s1">'myapp.pyz'</span><span class="p">,</span> <span class="s1">'myapp'</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-84">要使应用程序在POSIX上可直接执行,请指定要使用的解释器。</span></p><div class="highlight-sh"><div class="highlight"><pre><span></span>$ python -m zipapp myapp -p <span class="s2">"/usr/bin/env python"</span>
|
||
$ ./myapp.pyz
|
||
<output from myapp>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-85">要替换现有归档上的shebang行,请使用<a class="reference internal" href="#zipapp.create_archive" title="zipapp.create_archive"><code class="xref py py-func docutils literal"><span class="pre">create_archive()</span></code></a>函数创建修改的归档:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">zipapp</span>
|
||
<span class="gp">>>> </span><span class="n">zipapp</span><span class="o">.</span><span class="n">create_archive</span><span class="p">(</span><span class="s1">'old_archive.pyz'</span><span class="p">,</span> <span class="s1">'new_archive.pyz'</span><span class="p">,</span> <span class="s1">'/usr/bin/python3'</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-86">要立即更新文件,请使用<code class="xref py py-class docutils literal"><span class="pre">BytesIO</span></code>对象在内存中进行替换,然后再覆盖源。</span><span class="yiyi-st" id="yiyi-87">请注意,在覆盖文件时存在错误将导致原始文件丢失的风险。</span><span class="yiyi-st" id="yiyi-88">此代码不能防止此类错误,但生产代码应该这样做。</span><span class="yiyi-st" id="yiyi-89">此外,此方法将只有工作,如果存档适合内存:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">zipapp</span>
|
||
<span class="gp">>>> </span><span class="kn">import</span> <span class="nn">io</span>
|
||
<span class="gp">>>> </span><span class="n">temp</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span>
|
||
<span class="gp">>>> </span><span class="n">zipapp</span><span class="o">.</span><span class="n">create_archive</span><span class="p">(</span><span class="s1">'myapp.pyz'</span><span class="p">,</span> <span class="n">temp</span><span class="p">,</span> <span class="s1">'/usr/bin/python2'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'myapp.pyz'</span><span class="p">,</span> <span class="s1">'wb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||
<span class="gp">>>> </span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">temp</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-90">请注意,如果指定解释器,然后分发应用程序归档,则需要确保使用的解释器是可移植的。</span><span class="yiyi-st" id="yiyi-91">Windows的Python启动器支持POSIX <code class="docutils literal"><span class="pre">#!</span></code>的最常见形式</span><span class="yiyi-st" id="yiyi-92">线,但还有其他问题需要考虑:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-93">如果你使用“/ usr / bin / env python”(或其他形式的“python”命令,如“/ usr / bin / python”),你需要考虑你的用户可能有Python 2或Python 3作为它们的默认值,并且编写代码以在两个版本下工作。</span></li><li><span class="yiyi-st" id="yiyi-94">如果您使用显式版本,例如“/ usr / bin / env python3”,您的应用程序将不适用于没有该版本的用户。</span><span class="yiyi-st" id="yiyi-95">(这可能是你想要的,如果你没有使你的代码Python 2兼容)。</span></li><li><span class="yiyi-st" id="yiyi-96">没有办法说“python XY或更高版本”,所以要小心使用像“/ usr / bin / env python3.4”的确切版本,因为你需要为Python 3.5的用户更改你的shebang行,例如。</span></li></ul></div><div class="section" id="the-python-zip-application-archive-format"><h2><span class="yiyi-st" id="yiyi-97">28.4.5. </span><span class="yiyi-st" id="yiyi-98">The Python Zip Application Archive Format</span></h2><p><span class="yiyi-st" id="yiyi-99">Python自2.6版本起就能够执行包含<code class="docutils literal"><span class="pre">__main__.py</span></code>文件的zip文件。</span><span class="yiyi-st" id="yiyi-100">为了由Python执行,应用程序归档只需要是包含<code class="docutils literal"><span class="pre">__main__.py</span></code>文件的标准zip文件,该文件将作为应用程序的入口点运行。</span><span class="yiyi-st" id="yiyi-101">与任何Python脚本一样,脚本的父代(在这种情况下为zip文件)将放置在<a class="reference internal" href="sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal"><span class="pre">sys.path</span></code></a>上,因此可以从zip文件导入更多模块。</span></p><p><span class="yiyi-st" id="yiyi-102">zip文件格式允许将任意数据添加到zip文件。</span><span class="yiyi-st" id="yiyi-103">zip应用程序格式使用此功能在文件(<code class="docutils literal"><span class="pre">#!/path/to/interpreter</span></code>)前面添加标准POSIX“shebang”行。</span></p><p><span class="yiyi-st" id="yiyi-104">正式来说,Python zip应用程序格式是:</span></p><ol class="arabic simple"><li><span class="yiyi-st" id="yiyi-105">可选的shebang行,包含字符<code class="docutils literal"><span class="pre">b'#!'</span></code></span><span class="yiyi-st" id="yiyi-106">后跟解释器名称,然后是换行符(<code class="docutils literal"><span class="pre">b'\n'</span></code>)字符。</span><span class="yiyi-st" id="yiyi-107">解释器名称可以是OS“shebang”处理或Windows上的Python启动器可接受的任何名称。</span><span class="yiyi-st" id="yiyi-108">解释器应该在Windows上以UTF-8编码,在POSIX上在<a class="reference internal" href="sys.html#sys.getfilesystemencoding" title="sys.getfilesystemencoding"><code class="xref py py-func docutils literal"><span class="pre">sys.getfilesystemencoding()</span></code></a>中编码。</span></li><li><span class="yiyi-st" id="yiyi-109">标准zip文件数据,由<a class="reference internal" href="zipfile.html#module-zipfile" title="zipfile: Read and write ZIP-format archive files."><code class="xref py py-mod docutils literal"><span class="pre">zipfile</span></code></a>模块生成。</span><span class="yiyi-st" id="yiyi-110">zip文件内容<em>必须</em>包含一个名为<code class="docutils literal"><span class="pre">__main__.py</span></code>的文件(它必须位于zip文件的“根目录”中,即不能位于子目录中)。</span><span class="yiyi-st" id="yiyi-111">zipfile数据可以是压缩的或未压缩的。</span></li></ol><p><span class="yiyi-st" id="yiyi-112">如果应用程序归档具有shebang行,则它可以在POSIX系统上设置可执行位,以允许它直接执行。</span></p><p><span class="yiyi-st" id="yiyi-113">没有要求该模块中的工具用于创建应用程序存档 - 该模块是方便的,但是通过任何方式创建的上述格式的存档都可以被Python接受。</span></p></div></div></div> |