完全独立的虚拟环境
completely self-contained virtual environment
我创建了一个 python3
虚拟环境(明确避免符号链接,--copies
):
» python3 -m venv --without-pip --copies venv
这是我现在完整的虚拟环境:
» tree venv/
venv/
├── bin
│ ├── activate
│ ├── activate.csh
│ ├── activate.fish
│ ├── python
│ └── python3
├── include
├── lib
│ └── python3.4
│ └── site-packages
├── lib64 -> lib
└── pyvenv.cfg
我禁用 PYTHONPATH
,以确保没有任何东西从外面泄漏:
» PYTHONPATH=""
激活 venv:
» source venv/bin/activate
确认 activate
没有污染我的 PYTHONPATH
:
» echo $PYTHONPATH
(空白,符合预期)
我用的是右边python:
» which python
/foo/bar/venv/bin/python
但系统模块仍在访问中:
» python
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import unittest
>>> print(unittest)
<module 'unittest' from '/usr/lib/python3.4/unittest/__init__.py'>
>>>
我预计 import unittest
语句会失败,因为虚拟环境没有这样的模块。
我想知道:
- 为什么在 virtualenv 中访问系统包?
- 如何创建一个完全独立的虚拟环境?
如果我没记错的话,核心系统包是符号链接的,所以它们是相同的文件(部分原因是为了减小 virtualenv 的大小)。
默认不包含site-packages
目录,所以不会访问已经安装的第三方库
如果你想要真正隔离和 self-contained 虚拟环境,你最好看看 docker。
Virtualenv 实际上更像是一种管理不同应用程序的不同第 3 方安装包的轻量级方式。
编辑:
看起来 --always-copy
实际上并不总是复制所有文件:
virtualenv doesn't copy all .py files from the lib/python directory
深入研究源代码,看起来有一小部分模块被认为是 "required",这些是被复制的模块:
https://github.com/pypa/virtualenv/blob/ac4ea65b14270caeac56b1e1e64c56928037ebe2/virtualenv.py#L116
编辑 2:
您可以看到旧的 python 目录仍然出现在 sys.path
中,但是在 virtualenv 本身的目录之后:
>>> import sys
>>> sys.path
['', '/home/john/venv/lib/python2.7',
'/home/john/venv/lib/python2.7/plat-linux2',
'/home/john/venv/lib/python2.7/lib-tk',
'/home/john/venv/lib/python2.7/lib-old',
'/home/john/venv/lib/python2.7/lib-dynload', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/home/john/venv/local/lib/python2.7/site-packages',
'/home/john/venv/lib/python2.7/site-packages']
您可以在旧 Linux 上从源代码构建 python;那么 python 将是完全独立的,并且能够 运行 在许多 Linux.
上
在参考文献link中,是在容器环境中在centos 5上构建python 3.6的步骤细节。输出可用于许多 Linux,例如 debian 10、centos 6、7、8、photon 3、alpine,...
readline-devel
: 启用python命令行历史
sqlite-devel
: 启用 sqlite 支持
expat-devel
: 启用 xmltree 支持
bzip2-devel
: 启用 bzip2 支持
- 从源代码编译 SSL 以避免动态库 link
- 如果 python 的更高版本,也许您还需要编译更高版本的 gcc 以获得完整的 C++11 和更高版本的支持
- 编译后,您需要从 pypi.python.org 下载 setuptools 和 pip 并执行
python setup.py install
为这个独立 python. 准备好 pip
参考:https://github.com/stallpool/track-network-traffic#mitmproxy-for-manylinux
我创建了一个 python3
虚拟环境(明确避免符号链接,--copies
):
» python3 -m venv --without-pip --copies venv
这是我现在完整的虚拟环境:
» tree venv/
venv/
├── bin
│ ├── activate
│ ├── activate.csh
│ ├── activate.fish
│ ├── python
│ └── python3
├── include
├── lib
│ └── python3.4
│ └── site-packages
├── lib64 -> lib
└── pyvenv.cfg
我禁用 PYTHONPATH
,以确保没有任何东西从外面泄漏:
» PYTHONPATH=""
激活 venv:
» source venv/bin/activate
确认 activate
没有污染我的 PYTHONPATH
:
» echo $PYTHONPATH
(空白,符合预期)
我用的是右边python:
» which python
/foo/bar/venv/bin/python
但系统模块仍在访问中:
» python
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import unittest
>>> print(unittest)
<module 'unittest' from '/usr/lib/python3.4/unittest/__init__.py'>
>>>
我预计 import unittest
语句会失败,因为虚拟环境没有这样的模块。
我想知道:
- 为什么在 virtualenv 中访问系统包?
- 如何创建一个完全独立的虚拟环境?
如果我没记错的话,核心系统包是符号链接的,所以它们是相同的文件(部分原因是为了减小 virtualenv 的大小)。
默认不包含site-packages
目录,所以不会访问已经安装的第三方库
如果你想要真正隔离和 self-contained 虚拟环境,你最好看看 docker。
Virtualenv 实际上更像是一种管理不同应用程序的不同第 3 方安装包的轻量级方式。
编辑:
看起来 --always-copy
实际上并不总是复制所有文件:
virtualenv doesn't copy all .py files from the lib/python directory
深入研究源代码,看起来有一小部分模块被认为是 "required",这些是被复制的模块:
https://github.com/pypa/virtualenv/blob/ac4ea65b14270caeac56b1e1e64c56928037ebe2/virtualenv.py#L116
编辑 2:
您可以看到旧的 python 目录仍然出现在 sys.path
中,但是在 virtualenv 本身的目录之后:
>>> import sys
>>> sys.path
['', '/home/john/venv/lib/python2.7',
'/home/john/venv/lib/python2.7/plat-linux2',
'/home/john/venv/lib/python2.7/lib-tk',
'/home/john/venv/lib/python2.7/lib-old',
'/home/john/venv/lib/python2.7/lib-dynload', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/home/john/venv/local/lib/python2.7/site-packages',
'/home/john/venv/lib/python2.7/site-packages']
您可以在旧 Linux 上从源代码构建 python;那么 python 将是完全独立的,并且能够 运行 在许多 Linux.
上在参考文献link中,是在容器环境中在centos 5上构建python 3.6的步骤细节。输出可用于许多 Linux,例如 debian 10、centos 6、7、8、photon 3、alpine,...
readline-devel
: 启用python命令行历史sqlite-devel
: 启用 sqlite 支持expat-devel
: 启用 xmltree 支持bzip2-devel
: 启用 bzip2 支持- 从源代码编译 SSL 以避免动态库 link
- 如果 python 的更高版本,也许您还需要编译更高版本的 gcc 以获得完整的 C++11 和更高版本的支持
- 编译后,您需要从 pypi.python.org 下载 setuptools 和 pip 并执行
python setup.py install
为这个独立 python. 准备好 pip
参考:https://github.com/stallpool/track-network-traffic#mitmproxy-for-manylinux