自定义代码在virtualenv中的什么位置?


107

使用时应该遵循哪种目录结构virtualenv?例如,如果我正在构建WSGI应用程序并创建了一个名为virtualenv的虚拟环境,那么foobar我将从以下目录结构开始:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}

创建此环境后,将在哪里放置自己的环境:

  • python文件?
  • 静态文件(图像/等)?
  • “自定义”程序包,例如在线提供但在奶酪店中找不到的程序包?

关于virtualenv目录?

(假设我已经知道virtualenv目录本身应该在哪里。)


8
@jkp:我不同意。布局python应用程序的方式与为开发目的在virtualenv中定位该应用程序的方式不同。这是相关的,但不相同。请不要关闭重复。
jcdyer

Answers:


90

virtualenv提供python解释器实例,而不是应用程序实例。通常,您不会在包含系统默认Python的目录中创建应用程序文件,同样,也无需在virtualenv目录中定位应用程序。

例如,您可能有一个项目,其中有多个使用同一virtualenv的应用程序。或者,您可能正在使用virtualenv测试应用程序,该应用程序随后将与系统Python一起部署。或者,您可能正在打包一个独立的应用程序,在该应用程序中,将virtualenv目录放置在应用程序目录本身内的某个位置可能很有意义。

因此,总的来说,我认为这个问题没有一个正确的答案。而且,一件好事virtualenv是它支持许多不同的用例:不需要有正确的方法。


8
同意 我所做的所有事情都使用virtualenv,而且我从不将文件放在virtualenv目录中。Virtualenv需求对您的项目结构没有影响;只需激活virtualenv(或使用其bin / python),然后在任何需要它们的地方处理文件。
卡尔·梅耶

我也全心全意。我唯一一次触摸 virtualenv(我使用virtualenvwrapper)中的任何文件的时候是我想要编辑postactivatepostdeactivate挂钩的时候。
塔娜·布里姆霍尔

问题的解决方案可以通过具体可行的示例来更好地解决,包括权衡取舍,如该问题的其他答案所示。
andyfeller

2
将您的项目与virtualenv目录分开是比较干净的,但是与virtualenv系统python相比是无济于事的,因为virtualenv是修复损坏的依赖关系并隔离项目,以便它们可以使用不同的软件包版本,甚至使用python版本(我意识到这是预先编写的) -python3)。允许应用共享a 就像virtualenv使用virtualenv系统python一样,使应用容易受到virtualenv旨在解决的相同问题的困扰。There should be one obvious way to do it; 从逻辑上讲应该是1:1
达沃斯

@Ned:试图获得一些最佳实践,但是还不清楚:如果您有数十个项目,每个项目都有自己的virtualenv,那么如何跟踪哪个项目与哪个virtualenv一起使用?在每个文件夹的根目录中添加微小的shell脚本,以及与之一起使用的virtualenv的名称?
ccpizza

57

如果您经常只有几个项目,那么没有什么可以阻止您为每个项目创建一个新的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放在一个文件夹中,并以您正在处理的项目命名。

  /virtualenvs
    /foobar
      /bin
        {activate, activate.py, easy_install, python}
      /include
        {python2.6/...}
      /lib
        {python2.6/...}
  /foobar
    /mypackage1
      __init__.py
    /mypackage2
      __init__.py

这样,当出现问题时,您始终可以从新的virtualenv重新开始,并且项目文件保持安全。

另一个优点是您的多个项目可以使用相同的virtualenv,因此如果您有很多依赖项,则不必一遍又一遍地进行相同的安装。

$ cd /foobar
$ source ../virtualenvs/foobar/bin/activate
$ python 
>>> import mypackage2
>>>

对于经常需要设置和关闭virtualenvs的用户,看一下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”上工作时,您无需再担心virtualenvs的位置:

  /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
>>>

很整洁,不是吗?


非常同意有关使用的答案virtualenvwrapper。它巧妙地将virtualenv抽象化,同时仍然为您提供所有好处。
塔那·布里姆霍尔

5
但是强烈不同意将代码放入虚拟环境。如果您希望它“靠近”文件系统上的项目,则将venv/目录放置在与项目的目录相同的级别上BASE_DIR
罗伯·格兰特

30

因为virtualenvs不可重定位,所以我认为将项目文件放在virtualenv目录中是不明智的做法。virtualenv本身是一个生成的开发/部署工件(有点像.pyc文件),而不是项目的一部分;应该很容易将其吹散并随时重新创建,或者在新的部署主机上创建一个新的,等等。

实际上,许多人都使用virtualenvwrapper,它几乎完全从您的意识中删除了实际的virtualenvs,默认情况下将它们全部并排放置在$ HOME / .virtualenvs中。


完全同意这是一个不好的做法,很高兴指出,应该很容易修改和重新创建它,尤其是对于测试部署和浪费不必要的需求包而言。只是想补充一下,可以使用virtualenv进行重新定位,例如,virtualenv --relocatable myvenv请参见stackoverflow.com/a/6628642/1335793,因为您可以这样做并不意味着您应该这样做。
达沃斯

2

如果您为您的项目指定setup.py,则pip可以直接从版本控制中导入它。

做这样的事情:

$ virtualenv --no-site-packages myproject
$ . myproject/bin/activate
$ easy_install pip
$ pip install -e hg+http://bitbucket.org/owner/myproject#egg=proj

-e将投入该项目myproject/src,但它链接到myproject/lib/pythonX.X/site-packages/,所以所做的任何更改将得到回升立即从本地导入模块site-packages。的#egg位告诉pip您要给它为您创建的鸡蛋包装取什么名字。

如果您不使用--no-site-packages,请谨慎指定要使用-E选项将pip安装到virtualenv中

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.