alias导致virtualenv异常的分析和解法

简介: alias导致virtualenv异常的分析和解法

virtualenv 可以虚拟出一个独立的Python环境,在这个环境中安装的第三方库不会对系统中的Python产生影响。作为一个系统洁癖,我的系统中的Python环境只安装最主要的第三方库,我在开发Python项目的时候一般使用virtualenv生成的独立环境来安装项目需要的第三方库。但是如果同时使用了zsh的alias 和virtualenv,有可能就会导致virtualenv下面的python不能使用第三方库。

Python的运行方式

一般我们会使用以下两种方式之一来运行Python:

python xxx.py

或者在代码的第一行加上python的路径:

#! /usr/local/bin/python

这两种方式,使用的是系统中的Python来解释代码。

问题的复现

如果电脑上安装了Python2 和Python3, 那么想运行Python3写的代码的时候,我们可以使用以下方法来运行:

python3 xxx.py

但是由于有人不想写数字3, 于是就使用了zsh的alias功能,在 ~/.zshrc文件中,添加了一行:

alias python=/usr/local/bin/python3

在这种情况下,使用:

python xxx.py

就可以通过Python3来解析代码了。这种方式使用系统中的Python没有问题,但是如果在virtualenv下面可就惨了。

我们创建一个虚拟环境并激活,安装Python的requests库,再启动python并导入requests库, 并其代码流程如下:

$ virtualenv --python=python3 venv
$ . venv/bin/activate
$ pip install requests
$ python
>>>import requests

如果我们设置了上面的alias,那么你一定会得到下面的结果:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named requests

于是你打开 venv/lib/python3.5/site-packages却发现requests安安静静的躺在里面。于是你百思不得其解,明明pip 是把requests安装在虚拟环境下面的,为什么Python不能正常导入呢?于是你再执行以下代码查看环境变量:

import sys
print(sys.path)

你看到的可能是下面的结果:

['',
'/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python35.zip',
'/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5',
'/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin',
'/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload',
'/usr/local/lib/python3.5/site-packages']

全部是系统下面Python的路径,和你的virtualenv 没有一点点的关系。

然后你退出Python,在虚拟环境下面打印PATH,你却发现:

$ echo $PATH
/Users/kingname/jikexueyuan/class_spider_basic/program/mongodb/venv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

你的virtualenv环境好好的躺在你的环境变量的最前面。于是你快要疯掉了,到底是什么鬼,怎么会发生如此灵异的事件?系统不应该是首先找环境变量第一个位置下面的Python吗?怎么会跳过虚拟环境,去打开了系统中的Python呢?应该直接打开虚拟环境下面的Python才对啊!

问题原因

问题的根源就在你的alias上面。

zsh 的alias的优先级是非常高的,它会首先替换为等号后面的内容,然后再执行。那么即使在虚拟环境下,在终端输入 python并回车以后,实际执行的代码是:

/usr/local/bin/python3

你使用了绝对路径打开了系统中的Python3。

而由于你没有对pip 设定alias, 因此你使用pip 安装requests的时候,它调用的是虚拟环境下面的pip,所以requests会正确安装在虚拟环境下面。

解决问题

解决办法有两个:

  1. ~/.zshrc中删除下面的代码,并重启终端:
alias python=/usr/local/bin/python3
  1. ~/.zshrc中的:
alias python=/usr/local/bin/python3

修改为

alias python=python3
目录
相关文章
|
1月前
|
算法 Shell 开发者
【Conan 入门教程 】Conan 2.1中的打印方式/输出管理
【Conan 入门教程 】Conan 2.1中的打印方式/输出管理
31 1
|
1月前
C/C++test两步完成CMake项目静态分析
通过将C/C++test集成到CMake项目中,并根据项目的需要进行配置,可以在两步内完成CMake项目的静态分析。这样可以帮助开发人员及时发现并修复潜在的代码问题,提高代码质量和可靠性。
16 0
|
10月前
CMake常用命令——有无target
CMake常用命令——有无target
105 1
|
9月前
|
程序员 数据安全/隐私保护 索引
【python基础知识】11.如何debug -常见报错原因及排查思路 - 思维篇
【python基础知识】11.如何debug -常见报错原因及排查思路 - 思维篇
184 0
|
11月前
|
算法 Python
PID算法的详细推导及python代码
本文基于PID算法讲述了PID详细计算过程,给出python代码示例
140 0
|
Python
python中关于IndentationError: expected an indented block 中不易察觉修改原代码错误的解法
python中关于IndentationError: expected an indented block 中不易察觉修改原代码错误的解法
1222 0
python中关于IndentationError: expected an indented block 中不易察觉修改原代码错误的解法
|
编解码 并行计算
再论WRF模式报错:traj_opt is zero, but num_traj is not zero ,如何解决问题,成功运行
再论WRF模式报错:traj_opt is zero, but num_traj is not zero ,如何解决问题,成功运行
再论WRF模式报错:traj_opt is zero, but num_traj is not zero ,如何解决问题,成功运行
|
编译器
【UVM避坑】记录 UVM / SV 使用过程中遇到的琐碎问题
【UVM避坑】记录 UVM / SV 使用过程中遇到的琐碎问题
1024 0
【UVM避坑】记录 UVM / SV 使用过程中遇到的琐碎问题
|
Python
解决问题:安装了python,却提示 No module named ‘pip‘
解决问题:安装了python,却提示 No module named ‘pip‘
268 0
|
Python
Python基础-常见问题:运行代码时提示“SyntaxError: expected an indented block”,怎么解决呢?
Python基础-常见问题:运行代码时提示“SyntaxError: expected an indented block”,怎么解决呢?
276 0