我正在寻找一种环境确实从 root 继承的解决方案,但寻找答案似乎有很多困惑。许多 OP 问题认为他们正在继承包,而实际上并非如此。所以,搜索结果找到了这些问题,但答案有反解(或者只是解释他们错了)。
也就是说,一个 OP 实际上有一个类似的目标。可以跨 Anaconda 环境共享包吗?这个 OP 说他们的硬盘空间不足。“共享”的含义应该在新环境中使用相同的安装包。答案(不接受)是使用--clone.
我还发现了这篇文章,新创建的 conda envs 是否从基础 env 继承所有包?它说不--clone共享包。在这篇文章中,OP 认为他们的新环境“共享”了包,然后得出“共享”包不存在的结论。
非分离anaconda环境有什么用?
我测试了--clone标志和 Conda Docs 指令以“构建相同的环境”选项。两个 env 目录具有相同的大小:2G+。
(base) $ conda list --explicit > spec-file.txt
# Produced Size On Disk: 2.14 GB (2,305,961,984 bytes)
(base) conda create --name myclone --clone root
# Produced Size On Disk, clone: 2.14 GB (2,304,331,776 bytes)
Run Code Online (Sandbox Code Playgroud)
唯一的区别是构建相同的环境再次下载包,克隆复制本地文件所需的时间要少得多。
我使用 Miniconda 将 CLI 工具部署到同事工作站。基本上,这些工具都使用相同的包,偶尔会有例外,当我需要在基本安装中添加我不想要的特定模块时。
目标是将 conda create 用于扩展类似于 的基本包的环境virtualenv --system-site-packages,而不是复制它们的安装。
回应@merv 和他指向这篇文章的链接(为什么要安装软件包而不是仅仅链接到特定环境?),其中说 Conda venvs 默认继承基础软件包。这个周末我有另一个机会来解决这个问题。这是基本情况:
下载Miniconda 安装程序。使用设置安装
_64我更新了 pip 和 setuptools,
conda 更新 pip setuptools
下面,我列出了以下软件包base:
(base) C:\Users\xtian>conda list
# packages in environment at C:\Users\xtian\Miniconda3_64:
#
# Name Version Build Channel
asn1crypto 1.3.0 py37_0
ca-certificates 2020.1.1 0
certifi 2019.11.28 py37_0
cffi 1.13.2 py37h7a1dbc1_0
chardet 3.0.4 py37_1003
conda 4.8.2 py37_0
conda-package-handling 1.6.0 py37h62dcd97_0
console_shortcut 0.1.1 3
cryptography 2.8 py37h7a1dbc1_0
idna 2.8 py37_0
menuinst 1.4.16 py37he774522_0
openssl 1.1.1d he774522_3
pip 20.0.2 py37_1
powershell_shortcut 0.0.1 2
pycosat 0.6.3 py37he774522_0
pycparser 2.19 py37_0
pyopenssl 19.1.0 py37_0
pysocks 1.7.1 py37_0
python 3.7.4 h5263a28_0
pywin32 227 py37he774522_1
requests 2.22.0 py37_1
ruamel_yaml 0.15.87 py37he774522_0
setuptools 45.1.0 py37_0
six 1.14.0 py37_0
sqlite 3.31.1 he774522_0
tqdm 4.42.0 py_0
urllib3 1.25.8 py37_0
vc 14.1 h0510ff6_4
vs2015_runtime 14.16.27012 hf0eaf9b_1
wheel 0.34.2 py37_0
win_inet_pton 1.1.0 py37_0
wincertstore 0.2 py37_0
yaml 0.1.7 hc54c509_2
Run Code Online (Sandbox Code Playgroud)
然后我成功地创建了新的 venv:
(base) C:\Users\xtian>conda create -n wsgiserver
Collecting package metadata (current_repodata.json): done
Solving environment: done
## Package Plan ##
environment location: C:\Users\xtian\Miniconda3_64\envs\wsgiserver
Proceed ([y]/n)? y
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
Run Code Online (Sandbox Code Playgroud)
这里我激活新的 wsgiserver 虚拟环境,列出包,最后用pip--but测试没有pip!我今天用 64 位和 32 位安装程序进行了测试:
(base) C:\Users\xtian>conda activate wsgiserver
(wsgiserver) C:\Users\xtian>conda list
# packages in environment at C:\Users\xtian\Miniconda3_64\envs\wsgiserver:
#
# Name Version Build Channel
(wsgiserver) C:\Users\xtian>pip
'pip' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)
否。推荐的工作流程是用于conda create --clone创建新的独立环境,然后改变该环境以添加其他包。或者,可以将模板环境转储到 YAML ( conda env export > env.yaml),对其进行编辑以包含或删除包,然后从中创建一个新环境 ( conda env create -f env.yaml -n foo)。
在大多数情况下,对这种浪费存储的担忧是没有根据的。1由于 Conda 使用硬链接来最小化冗余,因此新环境可能会占用比实际更多的空间。对此的更详细分析可以在问题中找到,为什么要安装软件包而不是仅链接到特定环境?.
它不受支持,但有可能。首先,让我们明确声明通过命令嵌套激活 Conda 环境conda activate --stack不会启用或帮助允许跨环境继承 Python 包。这是因为它不操作PYTHONPATH,而是只保持先前的活动环境开启PATH并跳过停用脚本。此 GitHub 问题 中提供了对此的更详细讨论。
既然我们已经避免了那个红鲱鱼,让我们来谈谈PYTHONPATH。可以使用此环境变量来包含site-packages要搜索的其他目录。所以,天真地,像
conda activate foo
PYTHONPATH=$CONDA_ROOT/lib/python3.7/site-packages python
Run Code Online (Sandbox Code Playgroud)
应该使用可用的base和foo包启动 Python 。使其工作的一个关键约束是新环境中的 Python 必须与base的 Python 匹配,包括次要版本(在本例中为 3.7.*)。
虽然这将实现包继承,但我们需要考虑:这实际上会节省空间吗?我认为在实践中它可能不会,这就是原因。
据推测,我们不想物理复制 Python 安装,但新环境必须安装 Python 以帮助约束求解我们想要的新包。为此,我们不仅应该匹配 Python 版本 ( conda create -n foo python=3.7),还应该匹配与base完全相同的构建:
# first check base's python
conda list -n base '^python$'
# EXAMPLE RESULT
# Name Version Build Channel
python 3.7.6 h359304d_2
# use this when creating the environment
conda create -n foo python=3.7.6=h359304d_2
Run Code Online (Sandbox Code Playgroud)
这将让 Conda 进行链接工作并在两种环境中使用相同的物理副本。但是,不能保证 Python 的依赖项也会重用base 中的包。事实上,如果有任何兼容的较新版本可用,它会下载并安装这些版本。
此外,假设我们现在安装scikit-learn:
conda install -n foo scikit-learn
Run Code Online (Sandbox Code Playgroud)
这将再次检查它的最新版本及其依赖项,而不管这些依赖项的旧但兼容版本是否已经通过base可用。因此,更多的包被不必要地安装到包缓存中。
这里的模式似乎是我们真的想找到一种方法让foo env 安装新包,但使用尽可能多的现有包来满足依赖关系。而这正是conda create --clone已经发生的事情。2
因此,我完全失去了为继承而烦恼的动力。
我推测,纯Python包的特殊情况下,它可能是合理的使用pip install --target从基地环境兼容包安装底座到的位置之外的基地。然后,用户可以PYTHONPATH在python从base启动之前将此目录添加到。
这不会是我的第一选择。我知道克隆策略是可以管理的;从长远来看,我不知道会发生什么。
[1]只要包缓存 ( pkgs_dirs)的位置和创建环境的位置(默认为envs_dirs)在同一卷上,这将保持不变。具有多个卷的配置应该使用 softlinks,这最终会产生相同的效果。除非有人手动禁用了这两种类型的链接,否则 Conda 将在默默地最小化冗余方面做得不错。
[2]从技术上讲,人们可能还会尝试使用该--offline标志来强制 Conda 使用它已经缓存的内容。但是,OP 的前提是附加包是新的,因此假设我们在缓存中已经有兼容版本可能并不明智。
| 归档时间: |
|
| 查看次数: |
4792 次 |
| 最近记录: |