Python 和 virtualenv - 为什么 python 版本用于命名子目录?

Python and virtualenv - why is the python version used to name subdirectories?

为什么 virtualenv 创建机制坚持使用 Python 版本命名子目录?我指的是 test_venv/venv3/lib/>>>python3.6<<</site-packages

当您使用 3.6 venv 时,您当然会获得 3.6 包。与 2.7 相同,意思是 2.7 包。如果没有事先 activate-ing venv,你就不能使用这些,所以混淆的风险似乎很低。

除其他事项外,人们经常会问为什么某些东西不起作用,这与 OS 系统路径或 python sys.path 有关。那些以 python 版本命名的子路径使得很难概括在哪里可以找到 site-packages.

编辑:以下是在 macOS 上,但我在 Ubuntu 18.04 VM 上得到大致相同的行为。

使用 virtualenv ./venv2

创建一个 python 2 虚拟环境

目录结构 tree -d -L 3 ./venv2/:

./venv2/
├── bin
├── include
│   └── python2.7 -> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
└── lib
    └── python2.7
        ├── config -> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config
        ├── distutils
        ├── encodings -> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings
        ├── lib-dynload -> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload
        └── site-packages

使用 python3 -m venv ./venv3

创建一个 python 3 虚拟环境

稍微好一点,但仍然影响站点包。

./venv3/
├── bin
├── include
└── lib
    └── python3.6
        └── site-packages

specification一致:

Running this command creates the target directory... And it creates an (initially empty) lib/pythonX.Y/site-packages (or Lib\site-packages on Windows) subdirectory.

如果你好奇的话,这就是实现它的 cpython bit

至于原因:它反映了(并且如前所述(并反映在规范和代码中)在 Windows 上有所不同)如何从 sys.prefix 构建搜索路径的行为(这反过来又是在这种情况下,根据您的 venv 中 python 可执行文件的位置确定)。其决议已在Modules/getpath.c中实施,并在评论中包含更详细的描述。

长话短说:它允许 venv 相对容易地使用现有代码来完成它需要的所有搜索路径处理工作。

因为系统可以容纳几个版本的python,所以命名约定允许区分站点包文件夹。

如果 python 解释器从 virtualev 或正常安装启动,然后选择正确的路径,那么在 virtualenv 中保持此命名约定比签入代码更容易。