alias导致virtualenv异常的分析和解法
virtualenv 可以虚拟出一个独立的Python环境,在这个环境中安装的第三方库不会对系统中的Python产生影响。作为一个系统洁癖,我的系统中的Python环境只安装最主要的第三方库,我在开发Python项目的时候一般使用virtualenv生成的独立环境来安装项目需要的第三方库。但是如果同时使用了zsh的alias 和virtualenv,有可能就会导致virtualenv下面的python不能使用第三方库。
Python的运行方式
一般我们会使用以下两种方式之一来运行Python:
1 | python xxx.py |
或者在代码的第一行加上python的路径:
1 | #! /usr/local/bin/python |
这两种方式,使用的是系统中的Python来解释代码。
问题的复现
如果电脑上安装了Python2 和Python3, 那么想运行Python3写的代码的时候,我们可以使用以下方法来运行:
1 | python3 xxx.py |
但是由于有人不想写数字3, 于是就使用了zsh的alias功能,在~/.zshrc
文件中,添加了一行:
1 | alias python=/usr/local/bin/python3 |
在这种情况下,使用:
1 | python xxx.py |
就可以通过Python3来解析代码了。这种方式使用系统中的Python没有问题,但是如果在virtualenv下面可就惨了。
我们创建一个虚拟环境并激活,安装Python的requests库,再启动python并导入requests库, 并其代码流程如下:
1 | $ virtualenv --python=python3 venv |
如果我们设置了上面的alias,那么你一定会得到下面的结果:
1 | Traceback (most recent call last): |
于是你打开venv/lib/python3.5/site-packages
却发现requests安安静静的躺在里面。于是你百思不得其解,明明pip 是把requests安装在虚拟环境下面的,为什么Python不能正常导入呢?于是你再执行以下代码查看环境变量:
1 | import sys |
你看到的可能是下面的结果:
1 | ['', |
全部是系统下面Python的路径,和你的virtualenv 没有一点点的关系。
然后你退出Python,在虚拟环境下面打印PATH,你却发现:
1 | $ echo $PATH |
你的virtualenv环境好好的躺在你的环境变量的最前面。于是你快要疯掉了,到底是什么鬼,怎么会发生如此灵异的事件?系统不应该是首先找环境变量第一个位置下面的Python吗?怎么会跳过虚拟环境,去打开了系统中的Python呢?应该直接打开虚拟环境下面的Python才对啊!
问题原因
问题的根源就在你的alias上面。
zsh 的alias的优先级是非常高的,它会首先替换为等号后面的内容,然后再执行。那么即使在虚拟环境下,在终端输入python
并回车以后,实际执行的代码是:
1 | /usr/local/bin/python3 |
你使用了绝对路径打开了系统中的Python3。
而由于你没有对pip 设定alias, 因此你使用pip 安装requests的时候,它调用的是虚拟环境下面的pip,所以requests会正确安装在虚拟环境下面。
解决问题
解决办法有两个:
- 在
~/.zshrc
中删除下面的代码,并重启终端:
1 | alias python=/usr/local/bin/python3 |
- 将
~/.zshrc
中的:
1 | alias python=/usr/local/bin/python3 |
修改为
1 | alias python=python3 |
本文首发地址: http://kingname.info/2016/06/27/alias-vs-virtualenv/转载请注明出处。