自定义代码在虚拟环境中的哪个位置?
使用virtualenv
时,应该遵循什么样的目录结构呢?比如说,如果我在创建一个WSGI应用,并且创建了一个叫foobar
的虚拟环境,我会从这样的目录结构开始:
/foobar
/bin
{activate, activate.py, easy_install, python}
/include
{python2.6/...}
/lib
{python2.6/...}
一旦这个环境创建好了,接下来我应该把自己的文件放在哪里呢:
- Python文件?
- 静态文件(比如图片等)?
- “自定义”包,比如那些网上有但在常用的包管理网站上找不到的?
这些文件应该和virtualenv
的目录有什么关系呢?
(假设我已经知道虚拟环境的目录应该放在哪里。)
4 个回答
因为虚拟环境(virtualenv)不能随意移动,所以我觉得把项目文件放在虚拟环境的目录里是不太好的做法。虚拟环境本身就像是一个生成的开发或部署的工具(有点像.pyc文件),它并不是项目的一部分;我们应该能够随时轻松地删除它并重新创建,或者在新的部署主机上创建一个新的虚拟环境等等。
实际上,很多人使用 virtualenvwrapper,这个工具几乎完全把虚拟环境隐藏起来,默认情况下把它们都放在 $HOME/.virtualenvs 这个文件夹里,方便管理。
如果你偶尔只有几个项目,完全可以为每个项目创建一个新的虚拟环境(virtualenv),然后把需要的包直接放进去:
/foobar
/bin
{activate, activate.py, easy_install, python}
/include
{python2.6/...}
/lib
{python2.6/...}
/mypackage1
__init__.py
/mypackage2
__init__.py
这样做的好处是,你总能找到属于这个项目的激活脚本。
$ cd /foobar
$ source bin/activate
$ python
>>> import mypackage1
>>>
如果你想更有条理,可以考虑把所有的虚拟环境放在一个文件夹里,并且给每个虚拟环境起个和项目相关的名字。
/virtualenvs
/foobar
/bin
{activate, activate.py, easy_install, python}
/include
{python2.6/...}
/lib
{python2.6/...}
/foobar
/mypackage1
__init__.py
/mypackage2
__init__.py
这样一来,当出现问题时,你可以随时从新建一个虚拟环境开始,而你的项目文件也能安全保存。
另一个好处是,多个项目可以共用同一个虚拟环境,这样如果有很多依赖包,就不用重复安装了。
$ cd /foobar
$ source ../virtualenvs/foobar/bin/activate
$ python
>>> import mypackage2
>>>
对于那些经常需要设置和删除虚拟环境的用户,使用virtualenvwrapper会更方便。
http://pypi.python.org/pypi/virtualenvwrapper
使用virtualenvwrapper,你可以
* create and delete virtual environments
* organize virtual environments in a central place
* easily switch between environments
在处理“foo”和“bar”这两个项目时,你再也不用担心你的虚拟环境在哪里了:
/foo
/mypackage1
__init__.py
/bar
/mypackage2
__init__.py
这就是你开始处理“foo”项目的方法:
$ cd foo
$ workon
bar
foo
$ workon foo
(foo)$ python
>>> import mypackage1
>>>
然后切换到“bar”项目也简单得很:
$ cd ../bar
$ workon bar
(bar)$ python
>>> import mypackage2
>>>
是不是很不错呢?
virtualenv
提供的是一个 Python 解释器的实例,而不是一个应用程序的实例。通常情况下,你不会在系统默认 Python 的目录下创建你的应用文件,同样也没有必要把你的应用放在 virtualenv
的目录里。
举个例子,你可能有一个项目,里面有多个应用程序都在使用同一个 virtualenv
。或者,你可能在用 virtualenv
测试一个应用,之后这个应用会用系统自带的 Python 来部署。再或者,你可能在打包一个独立的应用,这时候把 virtualenv
的目录放在应用目录里也是合理的。
所以,总的来说,我觉得这个问题没有一个绝对正确的答案。而 virtualenv
的一个好处就是它支持很多不同的使用场景:没有必要只有一种正确的方式。