Ubuntu + virtualenv = 一团糟?virtualenv 不喜欢 dist-packages,想要 site-packages
有人能告诉我在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
中访问本地系统的包。
所以我有几个问题:
- 我怎么让
virtualenv
指向某个dist-packages
呢? - 我应该指向哪个
dist-packages
?是/usr/lib/python2.6/dist-packages
还是/usr/local/lib/python2.6/dist-packages/
? /usr/lib/python2.6/site-packages
有什么用?里面什么都没有啊!- 路径是先到先得吗?如果我在
/usr/local/lib/python2.6/dist-packages/
里安装了一个新版本的包XYZ,而在/usr/lib/python2.6/dist-packages
里有一个旧版本,当我import xyz
时,哪个会被导入?我猜这是根据路径列表来决定的,对吧? - 为什么这这么让人困惑?我是不是漏掉了什么?
- 在哪里定义了
easy_install
应该安装到/usr/local/lib/python2.6/dist-packages
? - 这会影响
pip
吗?
感谢任何能帮我解答这些问题的人!
5 个回答
除非你是在做系统管理工具,或者是在开发一些可以被认为是新系统服务的东西,否则最好不要去动Ubuntu自带的Python安装。
如果你是在Ubuntu上开发或部署Python应用,建议你自己从源代码编译Python,打包好后再用它来部署。这样一来,所有的文件夹都会放在正确的位置,虚拟环境(virtualenv)也能正常工作。如果你要在服务器上部署多个Python应用,可以把你的Python放在像/home/python
或者/opt/python
这样的地方,或者其他不在你个人目录下的地方。确保你对开发者组(可能是users
)有写权限,这样大家就可以方便地添加包。
这样做还可以让你有两层包的管理。你自己公司标准的工具可以安装在你的Python版本里,并成为你部署的打包文件的一部分,而只有特定应用需要的包可以放在虚拟环境里。
千万不要升级或修改Ubuntu系统自带的Python。
我觉得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里,对吗?
对的。
- 路径是先到先得吗?如果我在/usr/local/lib/python2.6/dist-packages里安装了一个新版本的包XYZ,而在/usr/lib/python2.6/dist-packages里有一个旧版本(来自Ubuntu的仓库/apt-get),那么当我导入xyz时,会导入哪个版本?我假设这是根据路径列表来决定的,是吗?
sys.path是按顺序扫描的。唯一有点奇怪的是,.pth文件的顺序可能和一些人预期的不一样。但如果你用pip来处理所有事情(也就是说,除了安装pip本身、预编译的包和本地目录的快照),你就不会有太多.pth文件了。
- 为什么这这么让人困惑?我是不是漏掉了什么?
这个文档写得不太好。我是通过在网上搜索才弄明白的。
- 这会影响pip吗?
会的,pip会自动安装到/usr/local/lib/pythonVERSION/site-packages里。使用“pip install -E $VIRTUAL_ENV packagename”可以在虚拟环境中安装包。
我有点想通过把 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 可以检查。