目前没有看到类似的文章,所以我打算分享一下相关经验
python本身功能非常有限,如果要实现科学运算,机器学习等功能,则需要涉及到第三方包(比较熟知的如numpy,opencv,pytorch等)
但是,对于不同的程序,其引用的第三方包也不同,并且这些第三方包也会引用其他特定版本的第三方包,当程序逐渐增多时,安装的第三方包也会增多,也就越来越容易出现冲突,最终会使配置环境的成本变得无法接受,导致python环境被锁死,无法再做更改。
举个例子:
一个虚拟环境就是一个独立的python,除了自带包使用了主环境外,第三方包(site-packages),脚本(scripts),甚至包括python解释器(python.exe)都是独立的。
当启动虚拟环境时(通常会使用启动脚本activate.bat),系统变量PATH中与python有关的环境变量会临时切换到虚拟环境的文件路径,直到退出虚拟环境,环境变量恢复为主环境的文件路径。
总结来说,虚拟环境,不如说就是同时安装了多个python,然后通过环境变量控制当前使用哪个python
有了虚拟环境后,我们就可以依据用途,分别在不同的虚拟环境中安装不同的包,这样就能缓解依赖地狱问题。
已经有很多人做过教程了,这里推荐一个比较简单的视频教程:视频链接
原则上来说,为了避免出现依赖错误,每个虚拟环境的包都应该独立安装。但是有些包会非常大,并且版本对代码的影响比较小,所以如果在虚拟环境中再装一次,会比较占用硬盘的空间。
这里以PyTorch为例子,这个深度学习框架包含torch核心,torchAudio,torchVision三部分,但实际上一个包可能不止一个文件夹,合计大约4GB左右的空间
我们可能会直接使用github上的现有工程,通常会使用requirements.txt生成虚拟环境并安装所需的包。但如果每个工程都要安装一遍PyTorch的话,下载所需的时间,和占用的空间就不能接受了。而且文件实质上是一样的,强迫症总会感觉不舒服的。
如果是这样的话,就非常简单了,只需要在创建虚拟环境时带上--system-site-packages
参数即可,如下
PS C:\Users\userName>python -m venv --system-site-packages myVenv
这个参数允许在不复制主环境的第三方包的情况下访问主环境的第三方包。
不过,这种引用方式还得依赖主环境的包的安装,而这又会可能导致主环境变得不稳定。
我们可以使用符号链接来实现对其他环境中特定文件夹的引用。
符号链接在系统层面中类似于快捷方式,访问符号链接将会自动跳转到被链接的文件夹
而与快捷方式不同的是,在应用层面,符号链接会被当作实际的文件夹,应用在访问符号链接时并不会察觉到路径出现了变化。
所以,可以使用符号链接代替原本需要安装的包,将其链接到其他环境中已安装的包。
这里我采取的方案是替换site-package里对应的包,而scripts保持原样,因为这个文件夹通常不大,但文件比较多不太好处理
在有Pytorch的主环境或虚拟环境,使用pip查询依赖的文件
(MachineLearning) C:\Users\userName>pip show torch -f >> out.txt
#通常文件列表会非常长,超出控制台显示上限,所以可以输出到out.txt中
虽然文件很多,但我们只需要关注script文件夹以及顶级路径,大概扫一眼,也就只有caffe2,torch,torchgen这三个文件夹
没什么多说的,直接复制就好
这里我写了一个ps1脚本,只需要把创建符号链接的文件夹填进去,然后用powershell运行就可以了
注意,如果已经重复安装了,则要删除对应的文件夹
$dirList = #这里填写site-packages里需要链接的文件夹列表
"caffe2",
"tensorboard",
"tensorboard_data_server",
"tensorboard_data_server-0.6.1.dist-info",
"tensorboard_plugin_wit",
"tensorboard_plugin_wit-1.8.1.dist-info",
"tensorboard-2.10.1.dist-info",
"torch",
"torch-1.13.0+cu117.dist-info",
"torchaudio",
"torchaudio-0.13.0+cu117.dist-info",
"torchvision",
"torchvision-0.14.0+cu117.dist-info",
"torchgen"
$linkPath = "C:\Users\userName\myVenv\Lib\site-packages\" #这里写新环境的site-packages路径
$RealPath = "C:\Users\userName\MachineLearning\Lib\site-packages\" #这里写原环境的site-packages路径
for($i = 0; $i -lt $dirList.Count; $i++)
{
$linkFullPath = $linkPath+$dirList[$i]
$realFullPath = $realPath+$dirList[$i]
New-Item -ItemType SymbolicLink -Path $linkFullPath -Target $realFullPath
}
运行后,新环境的site-packages中出现带箭头的文件夹,就成功了
之后可以在新环境中使用
(myVenv) C:\Users\userName>pip list -l
来检查被链接的包是否能正常识别
在链接完成后,请尽量避免在新环境中安装新的包,特别是不要尝试卸载被链接的包,否则会影响到原环境的文件。