我创建了一个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
语句失败,因为虚拟环境没有这样的模块。
我想知道:
答案 0 :(得分:7)
如果我没记错,核心系统包是符号链接的,所以它们是相同的文件(部分是为了保持virtualenv的大小)。
默认情况下不包含site-packages
目录,因此它不会访问已安装的第三方库。
如果您想要真正独立且独立的虚拟环境,最好不要关注docker。
Virtualenv实际上更像是一种轻量级的方式来管理不同应用程序的不同第三方安装包。
编辑:
看起来--always-copy
实际上并不总是复制所有文件:
virtualenv doesn't copy all .py files from the lib/python directory
深入挖掘源代码,看起来有一小部分被认为是“必需”的模块,这些模块被复制了:
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']