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

248 lines
39 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-venv"><h1><span class="yiyi-st" id="yiyi-10">28.3. <a class="reference internal" href="#module-venv" title="venv: Creation of virtual environments."><code class="xref py py-mod docutils literal"><span class="pre">venv</span></code></a> — 虚拟环境的创建</span></h1><div class="versionadded"><p><span class="yiyi-st" id="yiyi-11"><span class="versionmodified">版本3.3中的新功能。</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/venv/">Lib / venv /</a></span></p><p><span class="yiyi-st" id="yiyi-13"><a class="reference internal" href="#module-venv" title="venv: Creation of virtual environments."><code class="xref py py-mod docutils literal"><span class="pre">venv</span></code></a> 模块与它们自己的网站目录,选择分离系统站点目录,为创建轻量级的"虚拟环境"提供支持。</span><span class="yiyi-st" id="yiyi-14">每个虚拟环境都有他自己的python二进制文件允许在里面创建另一个版本的python同时有自己独立的开发环境可以在里面安装各种只在这个环境里面使用的包</span></p><p><span class="yiyi-st" id="yiyi-15">有关Python虚拟环境的更多信息请参见<span class="target" id="index-1"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0405"><strong>PEP 405</strong></a></span></p><div class="section" id="creating-virtual-environments"><h2><span class="yiyi-st" id="yiyi-16">28.3.1. </span><span class="yiyi-st" id="yiyi-17">Creating virtual environments</span></h2><p><span class="yiyi-st" id="yiyi-18">创建 <a class="reference internal" href="#venv-def"><span>虚拟环境</span></a> 是通过执行 <code class="docutils literal"><span class="pre">pyvenv</span></code> 脚本︰</span></p><pre><code class="language-python"><span></span><span class="n">pyvenv</span> <span class="o">/</span><span class="n">path</span><span class="o">/</span><span class="n">to</span><span class="o">/</span><span class="n">new</span><span class="o">/</span><span class="n">virtual</span><span class="o">/</span><span class="n">environment</span>
</code></pre><p><span class="yiyi-st" id="yiyi-19">运行此命令将创建目标目录 (创建任何不存在的父目录) 和 <code class="docutils literal"><span class="pre">pyvenv.cfg</span></code> 文件置于具有指向 Python 安装在运行命令从 <code class="docutils literal"><span class="pre">首页</span></code> 键。</span><span class="yiyi-st" id="yiyi-20">它还创建一个 <code class="docutils literal"><span class="pre">bin</span></code> (或 Windows <code class="docutils literal"><span class="pre">脚本</span></code> 子目录包含 <code class="docutils literal"><span class="pre">python</span></code> 的二进制文件 (或在 Windows 的情况下的二进制文件) 的副本。</span><span class="yiyi-st" id="yiyi-21">它还创建 (最初为空) <code class="docutils literal"><span class="pre">lib/pythonX.Y/site-packages</span></code> 子目录 (在 Windows 上,这是 <code class="docutils literal"><span class="pre">Lib\site 软件包</span></code>)。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-22">也可以看看</span></p><p class="last"><span class="yiyi-st" id="yiyi-23"><a class="reference external" href="https://packaging.python.org/en/latest/installing/#creating-virtual-environments">Python包装用户指南创建和使用虚拟环境</a></span></p></div><p><span class="yiyi-st" id="yiyi-24">在Windows上如果没有相关的PATH和PATHEXT设置则可能需要调用<code class="docutils literal"><span class="pre">pyvenv</span></code>脚本:</span></p><div class="highlight-none"><div class="highlight"><pre><span></span>c:\Temp&gt;c:\Python35\python c:\Python35\Tools\Scripts\pyvenv.py myenv
</pre></div></div><p><span class="yiyi-st" id="yiyi-25">或等效地:</span></p><div class="highlight-none"><div class="highlight"><pre><span></span>c:\Temp&gt;c:\Python35\python -m venv myenv
</pre></div></div><p><span class="yiyi-st" id="yiyi-26">该命令如果以<code class="docutils literal"><span class="pre">-h</span></code>运行,将显示可用的选项:</span></p><div class="highlight-none"><div class="highlight"><pre><span></span>usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
[--upgrade] [--without-pip]
ENV_DIR [ENV_DIR ...]
Creates virtual Python environments in one or more target directories.
positional arguments:
ENV_DIR A directory to create the environment in.
optional arguments:
-h, --help show this help message and exit
--system-site-packages Give the virtual environment access to the system
site-packages dir.
--symlinks Try to use symlinks rather than copies, when symlinks
are not the default for the platform.
--copies Try to use copies rather than symlinks, even when
symlinks are the default for the platform.
--clear Delete the contents of the environment directory if it
already exists, before environment creation.
--upgrade Upgrade the environment directory to use this version
of Python, assuming Python has been upgraded in-place.
--without-pip Skips installing or upgrading pip in the virtual
environment (pip is bootstrapped by default)
</pre></div></div><p><span class="yiyi-st" id="yiyi-27">根据如何调用<code class="docutils literal"><span class="pre">venv</span></code>功能,使用消息可以稍微改变,例如,</span><span class="yiyi-st" id="yiyi-28">引用<code class="docutils literal"><span class="pre">pyvenv</span></code>而不是<code class="docutils literal"><span class="pre">venv</span></code></span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-29"><span class="versionmodified">在版本3.4中更改:</span>默认安装pip添加了<code class="docutils literal"><span class="pre">--without-pip</span></code><code class="docutils literal"><span class="pre">--copies</span></code>选项</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-30"><span class="versionmodified">在版本3.4中已更改:</span>在早期版本中,如果目标目录已存在,则会出现错误,除非<code class="docutils literal"><span class="pre">--clear</span></code><code class="docutils literal"><span class="pre">--upgrade</span></code></span><span class="yiyi-st" id="yiyi-31">现在,如果指定了现有目录,则删除其内容,并且处理该目录,就好像它是新创建的。</span></p></div><p><span class="yiyi-st" id="yiyi-32">The created <code class="docutils literal"><span class="pre">pyvenv.cfg</span></code> file also includes the <code class="docutils literal"><span class="pre">include-system-site-packages</span></code> key, set to <code class="docutils literal"><span class="pre">true</span></code> if <code class="docutils literal"><span class="pre">venv</span></code> is run with the <code class="docutils literal"><span class="pre">--system-site-packages</span></code> option, <code class="docutils literal"><span class="pre">false</span></code> otherwise.</span></p><p><span class="yiyi-st" id="yiyi-33">除非给出<code class="docutils literal"><span class="pre">--without-pip</span></code>选项,否则将调用<a class="reference internal" href="ensurepip.html#module-ensurepip" title='ensurepip: Bootstrapping the "pip" installer into an existing Python installation or virtual environment.'><code class="xref py py-mod docutils literal"><span class="pre">ensurepip</span></code></a>以将<code class="docutils literal"><span class="pre">pip</span></code>引导到虚拟环境中。</span></p><p><span class="yiyi-st" id="yiyi-34">多个路径可以给予<code class="docutils literal"><span class="pre">pyvenv</span></code>在这种情况下将在每个提供的路径根据给定的选项创建一个相同的virtualenv。</span></p><p><span class="yiyi-st" id="yiyi-35">一旦创建了venv它可以使用venv的二进制目录中的脚本“激活”。</span><span class="yiyi-st" id="yiyi-36">脚本的调用是平台特定的:</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-37">平台</span></th><th class="head"><span class="yiyi-st" id="yiyi-38">Shell</span></th><th class="head"><span class="yiyi-st" id="yiyi-39">命令激活虚拟环境</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-40">Posix</span></td><td><span class="yiyi-st" id="yiyi-41">bash / zsh</span></td><td><span class="yiyi-st" id="yiyi-42">$ source <venv>/ bin / activate</venv></span></td></tr><tr class="row-odd"><td></td><td><span class="yiyi-st" id="yiyi-43">fish</span></td><td><span class="yiyi-st" id="yiyi-44">$。</span><span class="yiyi-st" id="yiyi-45"><venv>/bin/activate.fish</venv></span></td></tr><tr class="row-even"><td></td><td><span class="yiyi-st" id="yiyi-46">csh / tcsh</span></td><td><span class="yiyi-st" id="yiyi-47">$ source <venv>/bin/activate.csh</venv></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-48">Windows</span></td><td><span class="yiyi-st" id="yiyi-49">cmd.exe</span></td><td><span class="yiyi-st" id="yiyi-50">C\&gt; <venv>\ Scripts \ activate.bat</venv></span></td></tr><tr class="row-even"><td></td><td><span class="yiyi-st" id="yiyi-51">PowerShell</span></td><td><span class="yiyi-st" id="yiyi-52">PS C\&gt; <venv>\ Scripts \ Activate.ps1</venv></span></td></tr></tbody></table><p><span class="yiyi-st" id="yiyi-53">您不具体<em>需要</em>来激活环境激活只是将venv的二进制目录添加到你的路径所以“python”调用venv的Python解释器你可以运行安装的脚本而不必使用他们的完整路径。</span><span class="yiyi-st" id="yiyi-54">但是安装在venv中的所有脚本都应该可以在不激活的情况下运行并且可以自动运行venv的Python。</span></p><p><span class="yiyi-st" id="yiyi-55">您可以通过在shell中键入“deactivate”来停用venv。</span><span class="yiyi-st" id="yiyi-56">确切的机制是特定于平台的例如Bash激活脚本定义了一个“deactivate”函数而在Windows上有称为<code class="docutils literal"><span class="pre">deactivate.bat</span></code><code class="docutils literal"><span class="pre">Deactivate.ps1</span></code></span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-57"><span class="versionmodified">新版本3.4</span> <code class="docutils literal"><span class="pre">fish</span></code><code class="docutils literal"><span class="pre">csh</span></code>激活脚本。</span></p></div><div class="admonition note" id="venv-def"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-58">注意</span></p><p><span class="yiyi-st" id="yiyi-59">虚拟环境(也称为<code class="docutils literal"><span class="pre">venv</span></code>是一个Python环境使得安装在其中的Python解释器库和脚本与安装在其他虚拟环境中的Python解释器库和脚本隔离安装在一个“系统”Python</span><span class="yiyi-st" id="yiyi-60">其中一个作为操作系统的一部分安装。</span></p><p><span class="yiyi-st" id="yiyi-61">venv是一个目录树它包含Python可执行文件和其他文件这些文件指示它是一个venv。</span></p><p><span class="yiyi-st" id="yiyi-62">常用的安装工具,例如<code class="docutils literal"><span class="pre">Setuptools</span></code><code class="docutils literal"><span class="pre">pip</span></code>,可以正常工作</span><span class="yiyi-st" id="yiyi-63">当venv处于活动状态时他们将Python软件包安装到venv中而不需要明确地通知。</span></p><p><span class="yiyi-st" id="yiyi-64">当活动时(即</span><span class="yiyi-st" id="yiyi-65">the venvs Python interpreter is running), the attributes <a class="reference internal" href="sys.html#sys.prefix" title="sys.prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.prefix</span></code></a> and <a class="reference internal" href="sys.html#sys.exec_prefix" title="sys.exec_prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.exec_prefix</span></code></a> point to the base directory of the venv, whereas <a class="reference internal" href="sys.html#sys.base_prefix" title="sys.base_prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.base_prefix</span></code></a> and <a class="reference internal" href="sys.html#sys.base_exec_prefix" title="sys.base_exec_prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.base_exec_prefix</span></code></a> point to the non-venv Python installation which was used to create the venv. </span><span class="yiyi-st" id="yiyi-66">如果venv不活动<a class="reference internal" href="sys.html#sys.prefix" title="sys.prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.prefix</span></code></a><a class="reference internal" href="sys.html#sys.base_prefix" title="sys.base_prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.base_prefix</span></code></a>相同,<a class="reference internal" href="sys.html#sys.exec_prefix" title="sys.exec_prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.exec_prefix</span></code></a><a class="reference internal" href="sys.html#sys.base_exec_prefix" title="sys.base_exec_prefix"><code class="xref py py-attr docutils literal"><span class="pre">sys.base_exec_prefix</span></code></a>他们都指向一个非venv Python安装</span></p><p><span class="yiyi-st" id="yiyi-67">当venv处于活动状态时将更改所有distutils配置文件的任何更改安装路径的选项都将被忽略以防止项目无意中安装在虚拟环境之外。</span></p><p class="last"><span class="yiyi-st" id="yiyi-68">When working in a command shell, users can make a venv active by running an <code class="docutils literal"><span class="pre">activate</span></code> script in the venvs executables directory (the precise filename is shell-dependent), which prepends the venvs directory for executables to the <code class="docutils literal"><span class="pre">PATH</span></code> environment variable for the running shell. </span><span class="yiyi-st" id="yiyi-69">在其他情况下应该没有必要激活venv - 脚本安装到venvs有一个shebang线指向venv的Python解释器。</span><span class="yiyi-st" id="yiyi-70">这意味着脚本将与该解释器一起运行,而不管<code class="docutils literal"><span class="pre">PATH</span></code>的值。</span><span class="yiyi-st" id="yiyi-71">在Windows上如果您安装了适用于Windows的Python Launcher在3.3中已添加到Python中请参阅<span class="target" id="index-2"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0397"><strong>PEP 397</strong></a>以获取更多详细信息才支持shebang行处理。</span><span class="yiyi-st" id="yiyi-72">因此在Windows资源管理器窗口中双击已安装的脚本应该使用正确的解释器运行脚本而不需要在<code class="docutils literal"><span class="pre">PATH</span></code>中对其venv进行任何引用。</span></p></div></div><div class="section" id="api"><h2><span class="yiyi-st" id="yiyi-73">28.3.2. </span><span class="yiyi-st" id="yiyi-74">API</span></h2><p><span class="yiyi-st" id="yiyi-75">上面描述的高级方法使用简单的API其为第三方虚拟环境创建者提供用于根据他们的需要定制环境创建的机制<a class="reference internal" href="#venv.EnvBuilder" title="venv.EnvBuilder"><code class="xref py py-class docutils literal"><span class="pre">EnvBuilder</span></code></a>类。</span></p><dl class="class"><dt id="venv.EnvBuilder"><span class="yiyi-st" id="yiyi-76"> <em class="property">class </em><code class="descclassname">venv.</code><code class="descname">EnvBuilder</code><span class="sig-paren">(</span><em>system_site_packages=False</em>, <em>clear=False</em>, <em>symlinks=False</em>, <em>upgrade=False</em>, <em>with_pip=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-77"><a class="reference internal" href="#venv.EnvBuilder" title="venv.EnvBuilder"><code class="xref py py-class docutils literal"><span class="pre">EnvBuilder</span></code></a>类在实例化时接受以下关键字参数:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-78"><code class="docutils literal"><span class="pre">system_site_packages</span></code> - 一个布尔值指示系统Python site-packages应该可用于环境默认为<code class="docutils literal"><span class="pre">False</span></code>)。</span></li><li><span class="yiyi-st" id="yiyi-79"><code class="docutils literal"><span class="pre">clear</span></code> - 一个布尔值如果为true将在创建环境之前删除任何现有目标目录的内容。</span></li><li><span class="yiyi-st" id="yiyi-80"><code class="docutils literal"><span class="pre">symlinks</span></code> - 一个布尔值指示是否尝试符号链接Python二进制文件以及任何必需的DLL或其他二进制文件例如。</span><span class="yiyi-st" id="yiyi-81"><code class="docutils literal"><span class="pre">pythonw.exe</span></code>),而不是复制。</span><span class="yiyi-st" id="yiyi-82">在Linux和Unix系统上默认为<code class="docutils literal"><span class="pre">True</span></code>但在Windows上为<code class="docutils literal"><span class="pre">False</span></code></span></li><li><span class="yiyi-st" id="yiyi-83"><code class="docutils literal"><span class="pre">upgrade</span></code> - 一个布尔值如果为true将使用正在运行的Python升级现有环境以便在该Python已就地升级时使用默认为<code class="docutils literal"><span class="pre">False</span></code></span></li><li><span class="yiyi-st" id="yiyi-84"><code class="docutils literal"><span class="pre">with_pip</span></code> - 一个布尔值如果为true则确保pip安装在虚拟环境中。</span><span class="yiyi-st" id="yiyi-85">这使用<a class="reference internal" href="ensurepip.html#module-ensurepip" title='ensurepip: Bootstrapping the "pip" installer into an existing Python installation or virtual environment.'><code class="xref py py-mod docutils literal"><span class="pre">ensurepip</span></code></a><code class="docutils literal"><span class="pre">--default-pip</span></code>选项。</span></li></ul><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-86"><span class="versionmodified">在版本3.4中已更改:</span>添加了<code class="docutils literal"><span class="pre">with_pip</span></code>参数</span></p></div><p><span class="yiyi-st" id="yiyi-87">第三方虚拟环境工具的创建者可以免费使用提供的<code class="docutils literal"><span class="pre">EnvBuilder</span></code>类作为基类。</span></p><p><span class="yiyi-st" id="yiyi-88">返回的env-builder是一个对象它有一个方法<code class="docutils literal"><span class="pre">create</span></code></span></p><dl class="method"><dt id="venv.EnvBuilder.create"><span class="yiyi-st" id="yiyi-89"> <code class="descname">create</code><span class="sig-paren">(</span><em>env_dir</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-90">此方法将包含虚拟环境的目标目录的路径(绝对或相对于当前目录)作为必需参数。</span><span class="yiyi-st" id="yiyi-91"><code class="docutils literal"><span class="pre">create</span></code>方法将在指定的目录中创建环境,或引入适当的异常。</span></p><p><span class="yiyi-st" id="yiyi-92"><code class="docutils literal"><span class="pre">EnvBuilder</span></code>类的<code class="docutils literal"><span class="pre">create</span></code>方法说明了可用于子类自定义的钩子:</span></p><div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">create</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env_dir</span><span class="p">):</span>
<span class="sd">"""</span>
<span class="sd"> Create a virtualized Python environment in a directory.</span>
<span class="sd"> env_dir is the target directory to create an environment in.</span>
<span class="sd"> """</span>
<span class="n">env_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">env_dir</span><span class="p">)</span>
<span class="n">context</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ensure_directories</span><span class="p">(</span><span class="n">env_dir</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">create_configuration</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">setup_python</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">setup_scripts</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">post_setup</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
</pre></div></div><p><span class="yiyi-st" id="yiyi-93"><a class="reference internal" href="#venv.EnvBuilder.ensure_directories" title="venv.EnvBuilder.ensure_directories"><code class="xref py py-meth docutils literal"><span class="pre">ensure_directories()</span></code></a><a class="reference internal" href="#venv.EnvBuilder.create_configuration" title="venv.EnvBuilder.create_configuration"><code class="xref py py-meth docutils literal"><span class="pre">create_configuration()</span></code></a><a class="reference internal" href="#venv.EnvBuilder.setup_python" title="venv.EnvBuilder.setup_python"><code class="xref py py-meth docutils literal"><span class="pre">setup_python()</span></code></a><a class="reference internal" href="#venv.EnvBuilder.setup_scripts" title="venv.EnvBuilder.setup_scripts"><code class="xref py py-meth docutils literal"><span class="pre">setup_scripts()</span></code></a><a class="reference internal" href="#venv.EnvBuilder.post_setup" title="venv.EnvBuilder.post_setup"><code class="xref py py-meth docutils literal"><span class="pre">post_setup()</span></code></a>可以覆盖。</span></p></dd></dl><dl class="method"><dt id="venv.EnvBuilder.ensure_directories"><span class="yiyi-st" id="yiyi-94"> <code class="descname">ensure_directories</code><span class="sig-paren">(</span><em>env_dir</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-95">创建环境目录和所有必需的目录,并返回上下文对象。</span><span class="yiyi-st" id="yiyi-96">这只是属性(例如路径)的持有者,供其他方法使用。</span><span class="yiyi-st" id="yiyi-97">只要指定<code class="docutils literal"><span class="pre">clear</span></code><code class="docutils literal"><span class="pre">upgrade</span></code>允许在现有环境目录上操作,就允许这些目录存在。</span></p></dd></dl><dl class="method"><dt id="venv.EnvBuilder.create_configuration"><span class="yiyi-st" id="yiyi-98"> <code class="descname">create_configuration</code><span class="sig-paren">(</span><em>context</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-99">在环境中创建<code class="docutils literal"><span class="pre">pyvenv.cfg</span></code>配置文件。</span></p></dd></dl><dl class="method"><dt id="venv.EnvBuilder.setup_python"><span class="yiyi-st" id="yiyi-100"> <code class="descname">setup_python</code><span class="sig-paren">(</span><em>context</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-101">在环境中创建Python可执行文件以及在WindowsDLL下的副本。</span><span class="yiyi-st" id="yiyi-102">在POSIX系统上如果使用特定的可执行文件<code class="docutils literal"><span class="pre">python3.x</span></code>,将会创建指向该可执行文件的符号链接<code class="docutils literal"><span class="pre">python</span></code><code class="docutils literal"><span class="pre">python3</span></code>,除非具有这些名称的文件已存在。</span></p></dd></dl><dl class="method"><dt id="venv.EnvBuilder.setup_scripts"><span class="yiyi-st" id="yiyi-103"> <code class="descname">setup_scripts</code><span class="sig-paren">(</span><em>context</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-104">在虚拟环境中安装适用于平台的激活脚本。</span></p></dd></dl><dl class="method"><dt id="venv.EnvBuilder.post_setup"><span class="yiyi-st" id="yiyi-105"> <code class="descname">post_setup</code><span class="sig-paren">(</span><em>context</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-106">可以在第三方实现中覆盖以在虚拟环境中预安装软件包或执行其他后创建步骤的占位符方法。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-107">此外,<a class="reference internal" href="#venv.EnvBuilder" title="venv.EnvBuilder"><code class="xref py py-class docutils literal"><span class="pre">EnvBuilder</span></code></a>提供了可以从<a class="reference internal" href="#venv.EnvBuilder.setup_scripts" title="venv.EnvBuilder.setup_scripts"><code class="xref py py-meth docutils literal"><span class="pre">setup_scripts()</span></code></a><a class="reference internal" href="#venv.EnvBuilder.post_setup" title="venv.EnvBuilder.post_setup"><code class="xref py py-meth docutils literal"><span class="pre">post_setup()</span></code></a>在子类中调用的实用程序方法,以帮助将自定义脚本虚拟环境。</span></p><dl class="method"><dt id="venv.EnvBuilder.install_scripts"><span class="yiyi-st" id="yiyi-108"> <code class="descname">install_scripts</code><span class="sig-paren">(</span><em>context</em>, <em>path</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-109"><em>path</em>是应包含子目录“common”“posix”“nt”的目录的路径每个目录包含指向环境中bin目录的脚本。</span><span class="yiyi-st" id="yiyi-110">在对占位符进行一些文本替换后会复制“common”和与<a class="reference internal" href="os.html#os.name" title="os.name"><code class="xref py py-data docutils literal"><span class="pre">os.name</span></code></a>对应的目录的内容:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-111"><code class="docutils literal"><span class="pre">__VENV_DIR__</span></code>将替换为环境目录的绝对路径。</span></li><li><span class="yiyi-st" id="yiyi-112"><code class="docutils literal"><span class="pre">__VENV_NAME__</span></code>替换为环境名称(环境目录的最终路径段)。</span></li><li><span class="yiyi-st" id="yiyi-113"><code class="docutils literal"><span class="pre">__VENV_PROMPT__</span></code>被替换为提示符(环绕名称由圆括号括起来并带有以下空格)</span></li><li><span class="yiyi-st" id="yiyi-114"><code class="docutils literal"><span class="pre">__VENV_BIN_NAME__</span></code>将替换为bin目录的名称<code class="docutils literal"><span class="pre">bin</span></code><code class="docutils literal"><span class="pre">Scripts</span></code>)。</span></li><li><span class="yiyi-st" id="yiyi-115"><code class="docutils literal"><span class="pre">__VENV_PYTHON__</span></code>将替换为环境的可执行文件的绝对路径。</span></li></ul><p><span class="yiyi-st" id="yiyi-116">允许存在目录(用于在升级现有环境时)。</span></p></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-117">还有一个模块级的方便功能:</span></p><dl class="function"><dt id="venv.create"><span class="yiyi-st" id="yiyi-118"> <code class="descclassname">venv.</code><code class="descname">create</code><span class="sig-paren">(</span><em>env_dir</em>, <em>system_site_packages=False</em>, <em>clear=False</em>, <em>symlinks=False</em>, <em>with_pip=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-119">使用给定的关键字参数创建<a class="reference internal" href="#venv.EnvBuilder" title="venv.EnvBuilder"><code class="xref py py-class docutils literal"><span class="pre">EnvBuilder</span></code></a>,并使用<em>env_dir</em>参数调用其<a class="reference internal" href="#venv.EnvBuilder.create" title="venv.EnvBuilder.create"><code class="xref py py-meth docutils literal"><span class="pre">create()</span></code></a>方法。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-120"><span class="versionmodified">在版本3.4中已更改:</span>添加了<code class="docutils literal"><span class="pre">with_pip</span></code>参数</span></p></div></dd></dl></div><div class="section" id="an-example-of-extending-envbuilder"><h2><span class="yiyi-st" id="yiyi-121">28.3.3. </span><span class="yiyi-st" id="yiyi-122">An example of extending <code class="docutils literal"><span class="pre">EnvBuilder</span></code></span></h2><p><span class="yiyi-st" id="yiyi-123">以下脚本显示了如何通过实现一个子类来扩展<a class="reference internal" href="#venv.EnvBuilder" title="venv.EnvBuilder"><code class="xref py py-class docutils literal"><span class="pre">EnvBuilder</span></code></a>该子类安装了setuptools和pip到创建的venv中</span></p><div class="highlight-python"><div class="highlight"><pre><span></span>import os
import os.path
from subprocess import Popen, PIPE
import sys
from threading import Thread
from urllib.parse import urlparse
from urllib.request import urlretrieve
import venv
class ExtendedEnvBuilder(venv.EnvBuilder):
"""
This builder installs setuptools and pip so that you can pip or
easy_install other packages into the created environment.
:param nodist: If True, setuptools and pip are not installed into the
created environment.
:param nopip: If True, pip is not installed into the created
environment.
:param progress: If setuptools or pip are installed, the progress of the
installation can be monitored by passing a progress
callable. If specified, it is called with two
arguments: a string indicating some progress, and a
context indicating where the string is coming from.
The context argument can have one of three values:
'main', indicating that it is called from virtualize()
itself, and 'stdout' and 'stderr', which are obtained
by reading lines from the output streams of a subprocess
which is used to install the app.
If a callable is not specified, default progress
information is output to sys.stderr.
"""
def __init__(self, *args, **kwargs):
self.nodist = kwargs.pop('nodist', False)
self.nopip = kwargs.pop('nopip', False)
self.progress = kwargs.pop('progress', None)
self.verbose = kwargs.pop('verbose', False)
super().__init__(*args, **kwargs)
def post_setup(self, context):
"""
Set up any packages which need to be pre-installed into the
environment being created.
:param context: The information for the environment creation request
being processed.
"""
os.environ['VIRTUAL_ENV'] = context.env_dir
if not self.nodist:
self.install_setuptools(context)
# Can't install pip without setuptools
if not self.nopip and not self.nodist:
self.install_pip(context)
def reader(self, stream, context):
"""
Read lines from a subprocess' output stream and either pass to a progress
callable (if specified) or write progress information to sys.stderr.
"""
progress = self.progress
while True:
s = stream.readline()
if not s:
break
if progress is not None:
progress(s, context)
else:
if not self.verbose:
sys.stderr.write('.')
else:
sys.stderr.write(s.decode('utf-8'))
sys.stderr.flush()
stream.close()
def install_script(self, context, name, url):
_, _, path, _, _, _ = urlparse(url)
fn = os.path.split(path)[-1]
binpath = context.bin_path
distpath = os.path.join(binpath, fn)
# Download script into the env's binaries folder
urlretrieve(url, distpath)
progress = self.progress
if self.verbose:
term = '\n'
else:
term = ''
if progress is not None:
progress('Installing %s ...%s' % (name, term), 'main')
else:
sys.stderr.write('Installing %s ...%s' % (name, term))
sys.stderr.flush()
# Install in the env
args = [context.env_exe, fn]
p = Popen(args, stdout=PIPE, stderr=PIPE, cwd=binpath)
t1 = Thread(target=self.reader, args=(p.stdout, 'stdout'))
t1.start()
t2 = Thread(target=self.reader, args=(p.stderr, 'stderr'))
t2.start()
p.wait()
t1.join()
t2.join()
if progress is not None:
progress('done.', 'main')
else:
sys.stderr.write('done.\n')
# Clean up - no longer needed
os.unlink(distpath)
def install_setuptools(self, context):
"""
Install setuptools in the environment.
:param context: The information for the environment creation request
being processed.
"""
url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py'
self.install_script(context, 'setuptools', url)
# clear up the setuptools archive which gets downloaded
pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz')
files = filter(pred, os.listdir(context.bin_path))
for f in files:
f = os.path.join(context.bin_path, f)
os.unlink(f)
def install_pip(self, context):
"""
Install pip in the environment.
:param context: The information for the environment creation request
being processed.
"""
url = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
self.install_script(context, 'pip', url)
def main(args=None):
compatible = True
if sys.version_info &lt; (3, 3):
compatible = False
elif not hasattr(sys, 'base_prefix'):
compatible = False
if not compatible:
raise ValueError('This script is only for use with '
'Python 3.3 or later')
else:
import argparse
parser = argparse.ArgumentParser(prog=__name__,
description='Creates virtual Python '
'environments in one or '
'more target '
'directories.')
parser.add_argument('dirs', metavar='ENV_DIR', nargs='+',
help='A directory to create the environment in.')
parser.add_argument('--no-setuptools', default=False,
action='store_true', dest='nodist',
help="Don't install setuptools or pip in the "
"virtual environment.")
parser.add_argument('--no-pip', default=False,
action='store_true', dest='nopip',
help="Don't install pip in the virtual "
"environment.")
parser.add_argument('--system-site-packages', default=False,
action='store_true', dest='system_site',
help='Give the virtual environment access to the '
'system site-packages dir.')
if os.name == 'nt':
use_symlinks = False
else:
use_symlinks = True
parser.add_argument('--symlinks', default=use_symlinks,
action='store_true', dest='symlinks',
help='Try to use symlinks rather than copies, '
'when symlinks are not the default for '
'the platform.')
parser.add_argument('--clear', default=False, action='store_true',
dest='clear', help='Delete the contents of the '
'environment directory if it '
'already exists, before '
'environment creation.')
parser.add_argument('--upgrade', default=False, action='store_true',
dest='upgrade', help='Upgrade the environment '
'directory to use this version '
'of Python, assuming Python '
'has been upgraded in-place.')
parser.add_argument('--verbose', default=False, action='store_true',
dest='verbose', help='Display the output '
'from the scripts which '
'install setuptools and pip.')
options = parser.parse_args(args)
if options.upgrade and options.clear:
raise ValueError('you cannot supply --upgrade and --clear together.')
builder = ExtendedEnvBuilder(system_site_packages=options.system_site,
clear=options.clear,
symlinks=options.symlinks,
upgrade=options.upgrade,
nodist=options.nodist,
nopip=options.nopip,
verbose=options.verbose)
for d in options.dirs:
builder.create(d)
if __name__ == '__main__':
rc = 1
try:
main()
rc = 0
except Exception as e:
print('Error: %s' % e, file=sys.stderr)
sys.exit(rc)
</pre></div></div><p><span class="yiyi-st" id="yiyi-124">此脚本也可以在<a class="reference external" href="https://gist.github.com/4673395">在线</a>下载。</span></p></div></div></div>