Ubuntu + virtualenv = 一团糟?virtualenv 不喜欢 dist-packages,想要 site-packages

14 投票
5 回答
9203 浏览
提问于 2025-04-15 13:19

有人能告诉我在Ubuntu 9.04上使用Python时发生了什么吗?

我想使用virtualenv,但是--no-site-packages这个选项在Ubuntu上似乎没什么作用。我用easy_install安装了virtualenv 1.3.3(我把它升级到了setuptools 0.6c9),一切看起来都安装在/usr/local/lib/python2.6/dist-packages这个地方。

猜测,用apt-get安装包时,它会放在/usr/lib/python2.6/dist-packages/里,对吧?

问题是,还有一个/usr/local/lib/python2.6/site-packages的文件夹,里面什么都没有。看virtualenv里的path,这个文件夹似乎是virtualenv用作备份的地方。所以即使我省略了--no-site-packages,我也无法在我的任何virtualenv中访问本地系统的包。

所以我有几个问题:

  1. 我怎么让virtualenv指向某个dist-packages呢?
  2. 我应该指向哪个dist-packages?是/usr/lib/python2.6/dist-packages还是/usr/local/lib/python2.6/dist-packages/
  3. /usr/lib/python2.6/site-packages有什么用?里面什么都没有啊!
  4. 路径是先到先得吗?如果我在/usr/local/lib/python2.6/dist-packages/里安装了一个新版本的包XYZ,而在/usr/lib/python2.6/dist-packages里有一个旧版本,当我import xyz时,哪个会被导入?我猜这是根据路径列表来决定的,对吧?
  5. 为什么这这么让人困惑?我是不是漏掉了什么?
  6. 在哪里定义了easy_install应该安装到/usr/local/lib/python2.6/dist-packages
  7. 这会影响pip吗?

感谢任何能帮我解答这些问题的人!

5 个回答

4

除非你是在做系统管理工具,或者是在开发一些可以被认为是新系统服务的东西,否则最好不要去动Ubuntu自带的Python安装。

如果你是在Ubuntu上开发或部署Python应用,建议你自己从源代码编译Python,打包好后再用它来部署。这样一来,所有的文件夹都会放在正确的位置,虚拟环境(virtualenv)也能正常工作。如果你要在服务器上部署多个Python应用,可以把你的Python放在像/home/python或者/opt/python这样的地方,或者其他不在你个人目录下的地方。确保你对开发者组(可能是users)有写权限,这样大家就可以方便地添加包。

这样做还可以让你有两层包的管理。你自己公司标准的工具可以安装在你的Python版本里,并成为你部署的打包文件的一部分,而只有特定应用需要的包可以放在虚拟环境里。

千万不要升级或修改Ubuntu系统自带的Python。

17

我觉得Mike Orr在虚拟环境邮件列表上的回答是最好的。注意提问者在两个地方都发布了这个问题。

邮件的原始内容:

很多年前,Debian创建了一个目录/usr/local/lib/pythonVERSION/site-packages,并把Python的程序编译成默认会查找这个目录。Ubuntu通常会跟随Debian的做法,所以也这么做了。但Python的开发者们不喜欢这样,因为这样会和本地安装的/usr/local/bin/python发生冲突,使用同一个site-packages目录。最后,Ubuntu决定放弃site-packages,改用dist-packages,这是他们自己起的名字,目的是为了避免冲突。如果你在网上搜索一下,可以找到这个长故事,可能在Python的bug跟踪器或者distutils的特别兴趣小组里。

这个系统是有效的,至少如果你使用Ubuntu的virtualenv包的话。有些人在Ubuntu上使用本地安装的virtualenv时遇到问题,因为一些神奇的sys.path条目没有被添加进去。我对--no-site-packages这个选项不太确定,因为我从来不使用这个选项:我直接用Ubuntu的包来运行PIL和mysqldb,因为有时候编译它们的C依赖项会很麻烦。(需要正确的头文件,Python会忽略这些头文件等等。)

所以Ubuntu的Python包会放在/usr/lib/pythonVERSION/dist-packages。或者出于某种原因放在python-support目录。本地安装的Python包默认会放在/usr/local/lib/pythonVERSION/dist-packages。每次我安装Ubuntu 9.04系统时,我都会运行:

$ sudo apt-get install python-setuptools (6.0c9)
$ sudo apt-get install python-virtualenv (1.3.3)
$ sudo easy_install pip
$ sudo pip install virtualenvwrapper

这样创建的virtualenv都能正常工作,虽然我没有尝试过--no-site-packages。

我正在尝试启动virtualenv,--no-site-packages这个选项在Ubuntu上似乎没有任何作用。我用easy_install安装了virtualenv 1.3.3(我已经把setuptools升级到0.6c9)。

这两个版本在Ubuntu 9.04里都有,所以你本地安装它们其实是让自己更麻烦。

而且一切似乎都安装在/usr/local/lib/python2.6/dist-packages里。

没错。

我假设使用apt-get安装包时,它会放在/usr/lib/python2.6/dist-packages里,对吗?

对的。

  1. 路径是先到先得吗?如果我在/usr/local/lib/python2.6/dist-packages里安装了一个新版本的包XYZ,而在/usr/lib/python2.6/dist-packages里有一个旧版本(来自Ubuntu的仓库/apt-get),那么当我导入xyz时,会导入哪个版本?我假设这是根据路径列表来决定的,是吗?

sys.path是按顺序扫描的。唯一有点奇怪的是,.pth文件的顺序可能和一些人预期的不一样。但如果你用pip来处理所有事情(也就是说,除了安装pip本身、预编译的包和本地目录的快照),你就不会有太多.pth文件了。

  1. 为什么这这么让人困惑?我是不是漏掉了什么?

这个文档写得不太好。我是通过在网上搜索才弄明白的。

  1. 这会影响pip吗?

会的,pip会自动安装到/usr/local/lib/pythonVERSION/site-packages里。使用“pip install -E $VIRTUAL_ENV packagename”可以在虚拟环境中安装包。

9

我有点想通过把 site-packages 链接到 dist-packages 来解决这个问题,但我觉得这样可能会影响到其他情况,比如你想从 Ubuntu 的软件源以外的地方安装一些扩展。我想不到除了调整 virtualenv 的源代码以外的其他解决办法(因为 Ubuntu 和 virtualenv 都很流行,我不会惊讶如果已经有调整过的版本存在)。

关于第二点,如果你使用的是 /usr/local/bin/python,那么你应该使用 /usr/local 版本的库(包括 site-packages),反之,如果你使用的是 /usr/bin/python,就要使用那个版本的库。

关于第三点,如果你从源代码安装了 /usr/bin/python 的扩展(不是通过 easy_install 或者 Ubuntu 的软件源),那里会有一些东西。

关于第四点,是的,路径中较早的条目会优先被使用。

关于第五点,easy_install 这个名字听起来简单,但它其实做了很多复杂的事情,尽管它很方便,但因为我们 Python 开发者一致认为这种为了方便而使用的复杂操作表面上看起来“简单”,所以它被小心翼翼地排除在标准 Python 库之外。

关于第六点,我觉得这是 Ubuntu 对 easy_install 的修改——如果没错的话,那就是在 Canonical 或其他 Ubuntu 维护者做出集体决策的地方定义的。

关于第七点,抱歉,我不知道——我手头没有最近的 Ubuntu 可以检查。

撰写回答