python - conda 环境可以继承基础包吗?

标签 python conda

我正在寻找一种环境确实从 root 继承的解决方案,但寻找答案似乎有很多困惑。许多 OP 问题认为他们正在继承包,而实际上并非如此。所以,搜索结果找到了这些问题,但答案有反解(或者只是解释他们错了)。

也就是说,一个 OP 实际上有一个类似的目标。 Can packages be shared across Anaconda environments?这个 OP 说他们的硬盘空间不足。 “共享”的含义应该在新环境中使用相同的安装包。答案(不接受)是使用 --clone .

我也找到了这个帖子,Do newly created conda envs inherit all packages from the base env?上面写着 --clone不共享包。在这篇文章中,OP 认为他们的新环境“共享”包,然后得出“共享”包不存在的结论。
What is the use of non-separated anaconda environments?

我测试了 --clone标志,以及对 "build identical environments" 的 Conda 文档说明选项。两个 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)

唯一的区别是构建相同的环境再次下载包,克隆复制本地文件所需的时间要少得多。

我使用 Miniconda 将 CLI 工具部署到同事工作站。基本上,这些工具都使用相同的包,偶尔会有异常(exception),当我需要在基本安装中添加我不想要的特定模块时。

目标是将 conda create 用于扩展类似于 virtualenv --system-site-packages 的基本包的环境。 ,并且不要重复他们的安装。

更新 2020-02-08

回应@merv 和他指向这篇文章的链接 (Why are packages installed rather than just linked to a specific environment?),其中说 Conda venvs 默认继承基础包。这个周末我有另一个机会来解决这个问题。这是基本情况:

已下载 Miniconda installer .使用设置安装
  • 为我安装
  • 安装位置:(C:\Users\xtian\Miniconda3_64)
    注意:我添加了 _64
  • 高级选项
  • 将 Anaconda 添加到系统 PATH 变量中,False
  • 将 Anaconda 注册为系统 Python 3.7,真

  • 我更新了 pip 和 setuptools,

    conda update 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
    

    然后我成功创建了新的 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
    

    这里我激活新的wsgiserver虚拟环境,列出包,最后用pip测试--但是没有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.
    

    最佳答案

    Conda 环境应该继承基础包吗?
    推荐的工作流程是使用 conda create --clone创建一个新的独立环境,然后改变该环境以添加其他包。或者,可以将模板环境转储到 YAML ( conda env export > env.yaml ),对其进行编辑以包含或删除包,然后从中创建一个新环境 ( conda env create -f env.yaml -n foo )。
    在大多数情况下,对这种浪费存储的担忧是没有根据的。 1 由于 Conda 使用硬链接(hard link)来最小化冗余,因此新环境可能会占用比实际更多的空间。对此的更详分割析可以在问题Why are packages installed rather than just linked to a specific environment? 中找到。 .
    Conda 环境可以继承基础包吗?
    它不受支持,但有可能。 首先,让我们明确声明 nested activation of Conda environments通过 conda activate --stack命令不启用或帮助允许跨环境继承 Python 包。这是因为它不操作 PYTHONPATH ,而是仅保留 PATH 上的先前事件环境并跳过停用脚本。更详细的讨论可以在 this GitHub Issue 中找到。 .
    既然我们已经避免了那个红鲱鱼,让我们谈谈 PYTHONPATH .可以使用这个环境变量来包含额外的 site-packages要搜索的目录。所以,天真地,像

    conda activate foo
    PYTHONPATH=$CONDA_ROOT/lib/python3.7/site-packages python
    
    应该使用 的包启动 Python底座 foo 对它可用。使其工作的一个关键约束是新环境中的 Python 必须与 匹配。底座 直到并包括次要版本(在本例中为 3.7.*)。
    考虑细节
    虽然这将实现包继承,但我们需要考虑:这实际上会节省空间吗?我认为在实践中它可能不会,这就是原因。
    据推测,我们不想物理复制 Python 安装,但新环境必须安装 Python 以帮助约束求解我们想要的新包。为此,我们不仅应该匹配 Python 版本( conda create -n foo python=3.7 ),还应该匹配与 完全相同的构建版本。底座 :
    # 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
    
    这将让 Conda 进行链接工作并在两种环境中使用相同的物理副本。但是,不能保证 Python 的依赖项也会重用 中的包。底座 .事实上,如果有任何兼容的较新版本可用,它会下载并安装这些版本。
    此外,假设我们现在安装 scikit-learn :
    conda install -n foo scikit-learn
    
    这将再次检查它的最新版本及其依赖项,而不管这些依赖项的旧但兼容版本是否已经通过 可用。底座 .因此,更多的包被不必要地安装到包缓存中。
    这里的模式似乎是我们真的很想找到一种方法来拥有 foo env 安装新包,但使用尽可能多的现有包来满足依赖关系。而这正是conda create --clone已经做了。 2
    因此,我完全失去了为继承而烦恼的动力。

    笔记
    我推测对于纯 Python 包的特殊情况,使用 pip install --target 可能是合理的。来自 底座 安装与 兼容的软件包的环境底座 之外的位置底座 .然后用户可以将此目录添加到 PYTHONPATH发布前 python来自 底座 .
    这不会是我的第一选择。我知道克隆策略是可以管理的;从长远来看,我不知道会发生什么。

    [1] 只要包缓存的位置( pkgs_dirs )和创建环境的位置(默认为 envs_dirs )在同一卷上,这将保持不变。具有多个卷的配置 should be using softlinks ,最终会产生相同的效果。除非有人手动禁用了这两种类型的链接,否则 Conda 将在默默地最小化冗余方面做得不错。
    [2] 从技术上讲,人们也可能尝试使用 --offline标志强制 Conda 使用它已经缓存的内容。但是,OP 的前提是附加包是新的,因此假设我们在缓存中已经有兼容版本可能并不明智。

    关于python - conda 环境可以继承基础包吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55222405/

    相关文章:

    python - Pandas 公历日期到朱利安

    python - 使用父实现 : leads to problems 从子类覆盖 __mul__

    javascript - 如何处理firebase中过期的用户ID token ?

    conda - rstudio 服务器错误 :/bin/sh: x86_64-conda_cos6-linux-gnu-cc: command not found

    installation - 在具有 conda 环境的 OSX 上安装 Galsim : fftw/tmv file failed to link correctly

    python - 如何从字典列表中的字典中获取值

    python - 从 OneHotEncoder 获取对应的特征

    anaconda - 为什么 Anaconda3 包垃圾目录没有被 'conda clean' 清除?

    python - conda env 中的 pip 错误

    css - 创建环境中的Jupyter笔记本custom.css