1. BUG 描述
-
环境一
- Ubuntu 16.04 中有多个 Python 版本,包括系统默认(即
sudo apt install python3
)Python3.5 以及一个通过源码安装的 Python 3.6 - 没有使用 anaconda 管理不同 Python 版本。
- Ubuntu 16.04 中有多个 Python 版本,包括系统默认(即
-
环境二:
- 有多个版本的Python,通过 anaconda 管理。
-
BUG细节
- 在指定Python环境(环境一的Python3.6,环境二中除base外其他anaconda环境)的系统路径(
sys.path
) 中有预料之外的路径 - 环境一的Python3.6的系统路径,就有系统默认Python3.5对应的
/home/ubuntu/.local
相关内容。 - 环境二的自定义env的系统路径中,有属于base的
~/anaconda/lib/python3.6/site-packages
路径。
- 在指定Python环境(环境一的Python3.6,环境二中除base外其他anaconda环境)的系统路径(
-
会导致什么问题?
- 只要在系统路径下,python/pip 就会使用对应的包。
- 以环境二为例,如果base中安装了numpy,在自定义env中要通过
pip install numpy
就会失败(因为通过系统路径查到,numpy已经安装成功了,所以就会忽略当前环境下的pip install numpy
)。
2. 问题解决
2.1 治标不治本的方法
- 由于不理解(也查不到相关资料)系统路径的添加逻辑,所以也不知道该在什么地方设置,没能找到治本的方法。
- 权宜之计,就是在py文件一开头,就先将自己所需环境的路径添加进去
import sys
sys.path.insert(0, '/path/to/site-packages')
- 这种方法勉强解决了之前的问题(引用其他Python版本的第三方库),但很麻烦。
2.2 治本的方法
- 不知道在哪里看到一条命令,可以查看
site-packages
,命令如下python -m site
,结果示例如下
sys.path = [
'/home/ubuntu/anaconda3/lib/python37.zip',
'/home/ubuntu/anaconda3/lib/python3.7',
'/home/ubuntu/anaconda3/lib/python3.7/lib-dynload',
'/home/ubuntu/.local/lib/python3.7/site-packages',
'/home/ubuntu/.local/lib/python3.7/site-packages/resample2d_cuda-0.0.0-py3.7-linux-x86_64.egg',
'/home/ubuntu/.local/lib/python3.7/site-packages/traj_conv_cuda-0.0.0-py3.7-linux-x86_64.egg',
'/home/ubuntu/.local/lib/python3.7/site-packages/certifi-2020.6.20-py3.7.egg',
'/home/ubuntu/anaconda3/lib/python3.7/site-packages',
]
USER_BASE: '/home/ubuntu/.local' (exists)
USER_SITE: '/home/ubuntu/.local/lib/python3.7/site-packages' (exists)
ENABLE_USER_SITE: True
- 可以看到,我们不需要的路径恰好是在最后的
USER_BASE
、USER_SITE
中定义的。看起来,只要把ENABLE_USER_SITE
设置为false
,就能够解决问题。 - 设置方法就是定义环境变量
PYTHONNOUSERSITE
,1为false,0为true。export PYTHONNOUSERSITE=1
- conda 环境中设置环境变量可通过
conda env config vars set PYTHONNOUSERSITE=1
2.3 原理探究
-
site模块文档。
- site 模块会在初始化的时候自动调用。
- 主要作用是在 module search path 中添加一些路径
- 可通过
-S
选项来关闭这个功能。 - 会最多构建四个 site packages 目录,如果四个路径中有空,则删除该路径
- 两个 head,
sys.prefix
sys.exec_prefix
- 两个 tail:
lib/site-packages
(Windows) 或lib/python*X.Y*/site-packages
(Linux) - 4个 site packages 就是 2 heads * tails
- 两个 head,
- 还有一些关于
pyvenv.cfg
的功能,这里不细说,需要了解看就看文档。
-
什么是 User Site
- 安装包的时候,通过
pip install --user xxx
实现。 USER_SITE
一般对应的文件夹就是~/.local/lib/pythonX.Y/site-packages
USER_BASE
对应的文件夹就是~/.local
- 安装包的时候,通过
-
为什么要有
--user
这个选项?- 参考资料:这里
- 主要是权限问题,默认安装在
/usr/local/lib/pythonX.Y
中,但这个需要特殊权限。 --user
是安装在~
的子目录中,没有权限问题。