首页 > 解决方案 > 如何优先考虑 conda 包而不是 pip 一?

问题描述

激活我的虚拟环境后,我看到conda list我的 pandas 版本是 0.24.0。当我对 执行相同操作时pip list,我看到版本是 0.22.0(可能是我在使用 conda 之前安装的旧版本)。当我在python(3.6)中导入pandas时,pandas版本是0.22.0。

为什么以及如何强制加载 conda 包?

编辑:MacOS High Sierra 10.13.1

标签: pythonpandaspippackageconda

解决方案


TL;DR 在底部的可能修复中

一些注释,这些可能会或可能不会回答问题,但我认为这比将所有内容都倾倒在评论中要好一些。这些假设您的环境已激活,对于这些示例,我的环境称为new36. 我也在使用 High Sierra 10.13.6 的 MacOS。

检查condapip位置

首先,让我们检查以确保conda两者pip都在相同的环境中。要查找周围的信息conda,请检查:

conda info

我得到以下信息:

active environment : new36
    active env location : /Users/mm92400/anaconda3/envs/new36
            shell level : 1
       user config file : /Users/mm92400/.condarc
 populated config files : /Users/mm92400/.condarc
          conda version : 4.6.8
    conda-build version : 3.0.27
         python version : 3.6.3.final.0
# extra info excluded

active env location是我们所关心的。这应该是一个包含以下目录的目录pip

which pip | head -n 1

/Users/mm92400/anaconda3/envs/new36/bin/pip

如果pip不位于所在目录下conda,这可能是问题的一部分。

验证python的导入路径

您应该能够通过以下方式检查 python 从何处获取文件sys.path

import sys

sys.path
['', '/Users/mm92400/anaconda3/envs/new36/lib/python36.zip', '/Users/mm92400/anaconda3/envs/new36/lib/python3.6', '/Users/mm92400/anaconda3/envs/new36/lib/python3.6/lib-dynload', '/Users/mm92400/anaconda3/envs/new36/lib/python3.6/site-packages']

这是一个list,这很重要。请注意,我的 Mac 上没有任何sys.path来自基于基本安装的文件/文件夹的目录conda,也没有任何框架安装的 python。将按顺序import搜索这些目录('' 是 cwd),拉下它找到的包的第一个实例。如果您有一个比 conda env 更早的元素 contains ,这就是您的问题。sys.pathpandas

冗长的蟒蛇

您还可以使用 python 的详细模式验证 pandas 包的来源python -v

# you have gotten here by running python -v in the terminal
# there's a whole bunch of comments that pop out that I'm going to omit here

# Now run
import pandas

~snip~
# code object from '/Users/mm92400/anaconda3/envs/new36/lib/python3.6/site-packages/pandas/__pycache__/_version.cpython-36.pyc'
import 'pandas._version' # <_frozen_importlib_external.SourceFileLoader object at 0x107952b00>
import 'pandas' # <_frozen_importlib_external.SourceFileLoader object at 0x104572b38>

请注意code object路径如何匹配我期望 python 从中获取该包的位置

可能的修复

你可以破解sys.path,虽然我不确定这是多么推荐。您可以优先考虑目录所在的位置,而无需在脚本中sys.path进行修改,例如:sys.path

env PYTHONPATH=$(find $CONDA_PREFIX -type d -name "site-packages" | head -n 1) python

这将带您进入口译员,sys.path看起来像:

import sys
sys.path
['', '/Users/mm92400/anaconda3/envs/new36/lib/python3.6/site-packages', ...]

现在它将检查的第一个目录是conda env站点包。因为sys.path是 a list,所以会按顺序遍历。确定要使用哪个目录的优先级的方法是将特定目录注入第一个目录sys.path。如果我要编写如下脚本:

import sys

print(f"I prioritized {sys.path[1]}")

并使用env PYTHONPATH=$(find $CONDA_PREFIX -type d -name "site-packages" | head -n 1) python somefile.py我会得到:

env PYTHONPATH=$(find $CONDA_PREFIX -type d -name "site-packages" | head -n 1) python somefile.py
I prioritized /Users/mm92400/anaconda3/envs/new36/lib/python3.6/site-packages

或者,您可以insert进入sys.path,但我可以明确地说,这是推荐的,而且非常脆弱:

import os, sys

try:
    conda_env = os.environ['CONDA_PREFIX']
except KeyError:
    raise KeyError("The env var $CONDA_PREFIX was not found. Please check that your conda environment was activated")

for root, dirs, files in os.walk(conda_env):
    if 'site-packages' in dirs:
        syspath_add = os.path.join(root, 'site-packages')
        break
else:
    raise FileNotFoundError("Couldn't find site-packages!")

sys.path.insert(0, syspath_add)

sys.path
# ['/Users/mm92400/anaconda3/envs/new36/lib/python3.6/site-packages', '', ...]

推荐阅读