返回介绍

第 5 章 虚拟环境

发布于 2024-01-23 21:41:46 字数 5393 浏览 0 评论 0 收藏 0

在处理Python应用程序时,经常需要部署、使用和测试你的应用程序。但由于外部依赖的问题,做起来实际上很麻烦。有许多原因会导致在你的操作系统上部署或运行应用程序失败,例如:

· 系统中没有需要的库;

· 系统中没有需要的库的正确版本;

· 对两个不同的应用程序可能需要同一个库的两个不同版本。

这会发生在应用部署的时候,或者稍后运行的时候。而通过系统管理器升级已安装的Python库则很可能在毫无征兆的情况下导致你的应用程序无法运行。

这一问题的解决方案是针对每个应用程序使用独立的库目录,同时包含自己的依赖。然后使用这个目录——而不是系统安装的那个目录——加载所需的Python模块。

工具virtualenv可以自动为你处理这些目录。安装之后,只需在运行时将目标目录作为它的参数传入即可。

$ virtualenv myvenv
Using base prefix '/usr'
New python executable in myvenv/bin/python3
Also creating executable in myvenv/bin/python
Installing Setuptools........................done.
Installing Pip...............................done.

运行后,virtualenv会创建lib/pythonX.Y目录并利用它安装setuptools和pip,它们是后续安装其他Python包所必需的。

可以通过对activate执行source命令来激活这个虚拟环境

$ source myvenv/bin/activate

一旦这么做,shell的提示符会加上虚拟环境的名字作为前缀。此时调用python会执行被复制到虚拟环境中的Python。可以通过读取sys.path环境变量来验证,它将会把虚拟环境目录作为首选组件。

可以通过调用deactivate命令随时停止并退出虚拟环境:

$ deactivate

就这么简单。

如果只想使用在虚拟环境中安装的Python一次的话,不用运行acivate。直接调用虚拟环境中的python二进制文件也可以正常工作:

$ myvenv/bin/python

到目前为止,尽管已经进入激活的虚拟环境中,但还不能访问系统中安装以及在系统中可用的任何模块。这没问题,但我们可能需要安装它们。要做到这一点,只需使用标准的pip命令,它可以将包安装在正确的位置而不会对现有系统做任何修改:

$ source myvenv/bin/activate
(myvenv) $ pip install six
Downloading/unpacking six
 Downloading six-1.4.1.tar.gz
 Running setup.py egg_info for package six

Installing collected packages: six
 Running setup.py install for six

Successfully installed six
Cleaning up...

好了,我们能够在这个虚拟环境中安装所有需要的库,然后从虚拟环境运行我们的应用程序,而不会对当前系统产生任何影响。那么,接下来很自然就会想到要基于依赖的列表写脚本来自动安装虚拟环境,如示例5.1所示。

示例 5.1  自动化的虚拟环境创建

virtualenv myappvenv
source myappvenv/bin/activate
pip install -r requirements.txt
deactivate

在某些特定场景下,仍然需要访问系统中安装的包。那么可以通过在创建虚拟环境时向virtualen命令传入--system-site-packages标志来实现。

你可能已经猜到,虚拟环境对自动运行单元测试集非常有用。这是一个非常通用的模式,它是如此的通用,以至于已经有名为tox的工具来专门解决这一问题(详见6.7节)。

最近,PEP 405(http://www.python.org/dev/peps/pep-0405/)定义的虚拟环境机制已经被Python 3.3接受。也就是说,虚拟环境的使用如此流行以至于如今它已经成为Python标准库的一部分。

venv模块是Python 3.3及以上版本的一部分,可以操作虚拟环境而无需使用virtualenv包或其他包。可以通过Python的-m标志来加载模块:

$ python3.3 -m venv
usage: venv [-h] [--system-site-packages] [--symlinks] [--clear] [--upgrade]
      ENV_DIR [ENV_DIR ...]
venv: error: the following arguments are required: ENV_DIR

构建虚拟环境现在变得非常简单:

$ python3.3 -m venv myvenv

在myvenv内部,可以找到当前环境的名为pyvenv.cfg的配置文件。默认情况下它并不包含很多配置项。其中的include-system-site-package作用和前面介绍过的virtualenv的参数--system-site-packages作用相同。

激活虚拟环境的机制同前面描述的一样,通过执行source命令激活脚本:

$ source myvenv/bin/activate
(myvenv) $

同样,可以调用deactivate退出虚拟环境。

venv模块的缺点就是它不会默认安装setuptools和pip。因此我们只能自己引导环境(如示例5.2所示),而不像vitualenv那样都帮我们做好。

示例 5.2  引导venv环境

(myvenv) $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/
ez_setup.py -O - | python
-2013-09-02 22:26:07-- https://bitbucket.org/pypa/setuptools/raw 
/bootstrap/ez_setup.py
Resolving bitbucket.org (bitbucket.org)... 131.103.20.168, 131.103.20.167
Connecting to bitbucket.org (bitbucket.org)|131.103.20.168|:443... 
connected.
HTTP request sent, awaiting response... 200 OK
Length: 11835 (12K) [text/plain]
Saving to: 'STDOUT'
100%[============================================>] 11,835   --.-K/s  in 0s   
2013-09-02 22:26:08 (184 MB/s) - written to stdout [11835/11835]
Downloading https://pypi.python.org/packages/source/s/setuptools/
setuptools-1.1.tar.gz
Extracting in /tmp/tmp228fqm
Now working in /tmp/tmp228fqm/setuptools-1.1
Installing Setuptools
running install
running bdist_egg
running egg_info
writing dependency_links to setuptools.egg-i
[...]
Adding setuptools 1.1 to easy-install.pth file
Installing easy_install script to /home/jd/myvenv/bin
Installing easy_install-3.3 script to /home/jd/myvenv/bin
Installed /home/jd/myvenv/lib/python3.3/site-packages/
setuptools-1.1-py3.3.egg
Processing dependencies for setuptools==1.1
Finished processing dependencies for setuptools==1.1

接下来可以通过easy_install安装pip:

(myvenv) $ easy_install pip
Searching for pip
Reading https://pypi.python.org/simple/pip/
Best match: pip 1.4.1
Downloading https://pypi.python.org/packages/source/p/pip/pip-1.4.1.tar. 
gz#md5=6afbb46aeb48abac658d4df742bff714
Processing pip-1.4.1.tar.gz
Writing /tmp/easy_install-hxo3b0/pip-1.4.1/setup.cfg
Running pip-1.4.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-hxo3b0
/pip-1.4.1/egg-dist-tmp-efgi80
warning: no files found matching '*.html' under directory 'docs'
warning: no previously-included files matching '*.rst' found under directory 
'docs/_build'
no previously-included directories found matching 'docs/_build/_sources'
Adding pip 1.4.1 to easy-install.pth file
Installing pip script to /home/jd/myvenv/bin
Installing pip-3.3 script to /home/jd/myvenv/bin

Installed /home/jd/myvenv/lib/python3.3/site-packages/pip-1.4.1-py3.3.egg
Processing dependencies for pip
Finished processing dependencies for pip

接下来就可以通过pip安装任何其他所需的包了。

所以尽管Python 3.3默认包含了venv模块,但是必须承认它有缺点,就是它不会默认做好一些你期望的工作。虽然写个小工具利用venv模拟virtualenv的默认行为并不难,但是,如果不是只针对Python 3.3及以上版本,那么实在没必要这么做。另外,pip引导代码已经并入Python 3.4中,这意味着引导问题在最近的Python版本中已经解决了。

不管怎样,大多数程序都要同时支持Python 2和Python 3,所以完全依赖venv不是最好的选择。最好的选择仍然是基于virtualenv。考虑它们的工作方式都一样,所以这应该不是什么问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文