我们使用python的时候,通常会安装很多的第三方包,为了不污染系统自带的python环境,我们通常会使用virtualenv.
首先,使用如下的命令看下系统自带的python使用的包路径
python -m site其中/usr/lib64/python2.7/site-packages就是我们直接使用pip install 安装的包所在的路径
![](http://image.uc.cn/s/wemedia/s/upload/2024/ac8a3d3454900ed3f494b076fa96fdd2.png)
使用如下的命令安装virtualenv包
pip install virtualenv![](http://image.uc.cn/s/wemedia/s/upload/2024/b5ec73711d4e82dddf1e64a17b749e4e.png)
使用如下命令在testenv目录中新建一个virtualenv
virtualenv testenv![](http://image.uc.cn/s/wemedia/s/upload/2024/2d3fd9da68b4bdd229436bb170ea34f2.png)
使用如下命令可以看到这个virtualenv里面的python使用的包路径是自己的.
bin/python -m site![](http://image.uc.cn/s/wemedia/s/upload/2024/d7e67479bf07282152d7919c03675d14.png)
使用如下的命令可以看到,这个virutalenv里面只有pip setuptools wheel这几个用于安装包的包
source bin/activatepip list![](http://image.uc.cn/s/wemedia/s/upload/2024/f228889b51540522ac2af3e034ee1243.png)
不过因为/usr/lib64/python2.7也在sys.path里面,所以系统自带的模块也可以被使用.
0x01 virtualenv是怎么实现的首先,看下系统自带的python和virtualenv中的python可执行文件,发现是同一个文件.说明python可执行文件和系统中的是同一个.
#md5sum bin/python /usr/bin/python![](http://image.uc.cn/s/wemedia/s/upload/2024/b7bbc664b906cfa39b5d8d45834f60c2.png)
我们先模拟一下virtualenv的实现逻辑,在~/toutiao/testenv下执行如下命令
#mkdir -p bin lib64/python2.7#cp /usr/bin/python bin/#bin/python -c 'import sys;print sys.path'发现sys.path和/usr/bin/python的值还是一样的.说明单纯把python可执行文件复制过去没有用.
![](http://image.uc.cn/s/wemedia/s/upload/2024/7a87308bc1031ebe6afa0bd58b6dd6d0.png)
再添加一些文件和目录,发现现在sys.path都变成我们新建的myenv目录下的目录了.
#touch lib64/python2.7/os.py#touch lib64/python2.7/site.py#mkdir lib64/python2.7/lib-dynload#myenv/bin/python -c 'import sys; print sys.prefix;print sys.exec_prefix;print sys.path'![](http://image.uc.cn/s/wemedia/s/upload/2024/9511dd5c4dd1b30f51ae239487dc1f4e.png)
说明python这个可执行文件在确定sys.prefix,sys.exec_prefix,进而构建sys.path的时候,会通过自己所在的目录进行os.py文件搜索,搜索过程从当前目录一直回退到根目录,直到第一个lib64/pythonX.Y/os.py出现的地方.其中X.Y表示python的版本.
我们还发现,比起virtualenv得到的环境,我们模拟的这个里面没有系统的/usr/lib64/python2.7,也没有自定义的site-package目录. 因为我们的site.py文件中没有添加任何内容.
同理,当我们使用virtualenv的时候,如果加上--system-site-packages选项,那么在得到的virtualenv中pip list可以看到在系统site-package中安装的包,这个选项也是在生成的site.py中添加了系统的site-package目录.
0xff 参考文献virtualenv的实现本身是cpython实现的时候自己带上的一个功能,后面被大家发现之后使用起来的.下面这篇文章详细介绍了相应的机制,本文只是介绍了其中最主要的部分.感兴趣的话可以看下.
http://carljm.github.io/pipvirtualenv-preso/#1