Python中主环境和virtualenv环境下的package冲突问题如何解决?

我在 D:\Python27 下安装了 Python,并在其中安装了 matplotlib,而 matplotlib 又依赖 backports.functools_lru_cache,所以在 D:\Python27\Lib\site-packages 目录下有 backports 包

然后我又用 virtualenv --system-site-packages venv 在 D:\Python27\venv 目录下生成了一个虚拟环境,然后在此虚拟环境下安装了 jupyter,而 jupyter 又依赖 backports.shutil_get_terminal_size,所以在 D:\Python27\venv\Lib\site-packages 目录下也有 backports 包

而且这两个 backports 包的内容又不一样,,

装完之后我启动 D:\Python27\venv 下的 iPython 结果它告诉我在 import matplotlib 时发生 from backports.functools_lru_cache import lru_cache 错误,,backports 下没有 functools_lru_cache

我猜测两个地方同时有 backports 包时,虚拟环境优先导入虚拟环境下的 backports,虚拟环境下的 backports 确实没有 functools_lru_cache

所以我就想在虚拟环境下用 pip install backports.functools_lru_cache 也安装 functools_lru_cache,,可是 pip 告诉我已经有 functools_lru_cache 了,,不让装,,我猜测是因为 pip 检测到了主环境下已经安装了 backports.functools_lru_cache,所以就不让我在虚拟环境下安装了

我又想了两种可能的办法:

1、把主环境下的 backports.functools_lru_cache 给卸载了,,在虚拟环境下安装,,可这样的话就只能在虚拟环境下才能使用 matplotlib 库了,,这肯定不行

2、安装虚拟环境时去掉--system-site-packages,,可这样的话虚拟环境和主环境下就得各安装一个 matplotlib 才能两个环境都有 matplotlib 用,,

我觉得出现这种状况的主要原因是,backports.functools_lru_cache 和 backports.shutil_get_terminal_size 这两个包明明不一样,,安装后的包名却都叫 backports,,其实在这种情况下,如果虚拟环境下的 backports 包下找不到 functools_lru_cache,,python 能主动再去主环境的 backports 包下去找一下也行,,

所以,,现在卡死了,,请问有没有遇到类似问题的??对这种情况官方有没有什么解决办法??


Python中主环境和virtualenv环境下的package冲突问题如何解决?

19 回复

没遇到过这个问题,因为 virtualenv 的目标是创造出一个干净的隔离环境,所以理论上所有的依赖都应该在 virtualenv 里,所以我的习惯是不使用 --system-site-packages

猜测:你使用的 pip 不是 virtualenv 里的

可以使用绝对路径引用 virualenv 里的 pip 重装一下依赖
假设刚建的虚拟环境在 /home/app/venv 下,用 /home/app/venv/bin/pip 安装所有依赖包并更新


核心解决方案是:使用虚拟环境隔离,并通过pip listpython -m site诊断路径。

当系统Python(主环境)和virtualenv的包混在一起,通常是环境没激活或PATH设置乱了。按这个步骤排查:

  1. 首先,确认你确实在虚拟环境里:

    # 在命令行执行,检查终端提示符或使用以下命令
    # Linux/macOS
    echo $VIRTUAL_ENV
    # Windows
    echo %VIRTUAL_ENV%
    

    如果没输出路径,说明虚拟环境没激活。用source venv/bin/activate(Linux/macOS)或venv\Scripts\activate(Windows)激活。

  2. 检查Python和pip的路径:

    which python   # Linux/macOS
    where python   # Windows
    which pip      # Linux/macOS
    where pip      # Windows
    

    确保它们指向你的虚拟环境目录(例如.../venv/bin/python),而不是/usr/bin/python

  3. 查看当前环境安装的包,确认隔离是否生效:

    pip list
    

    对比在虚拟环境外执行的结果,应该完全不同。

  4. 如果还有冲突,检查Python的模块搜索路径:

    import sys
    print(sys.path)
    

    确保虚拟环境的site-packages目录(如.../venv/lib/python3.9/site-packages)在系统路径之前。

常见踩坑点:

  • 用IDE时,没在项目设置里选对虚拟环境的Python解释器。
  • 在终端里激活了环境,但用IDE的终端或外部工具跑代码时又没激活。
  • 系统环境变量PYTHONPATH干扰,可以临时清掉试试:unset PYTHONPATH(Linux/macOS)或set PYTHONPATH=(Windows)。

一句话总结:确保虚拟环境正确激活并验证Python/pip路径。

可能是目录设错了,对不起,我用 python 的时候遇到的是这样的情况


我用的是 virtualenv 里的 pip,但是因为建虚拟环境时使用了–system-site-packages,所以即使用 virtualenv 里的 pip,它也会检查主环境里有没有要安装的 package

至于你说创建虚拟环境时不使用–system-site-packages,,这确实可以解决问题,,不过这样的话 numpy、scipy、pandas、matplotlib、sympy、scikit-learn 这些包我都要在主环境和虚拟环境下各装一份,,

还有一种更彻底的方法,不建虚拟环境,,直接把 jupyter 安装在主环境下,,可是 jupyter 依赖的包有 50 个以上,,把主环境的 site-packages 目录都给污染了,,感觉也不好

现在想到一种操作难度比较低、但比较“脏”的办法:

手动把 D:\Python27\Lib\site-packages\backports 目录下的 functools_lru_cache.py 文件拷贝到 D:\Python27\venv\Lib\site-packages\backports 目录下

已经测试,,问题确实解决了

不过感觉这种方法真的不太好,,

没有遇到过这种情况,我也来学习一下。

主环境啥都不装,只用 virtualenv,
可能因为我需求简单… 只需要在 命令行下跑点东西,写 py 也只用 atom 这种编辑器。

玩 python 建议还是每个项目下的依赖包各装一份,不需要的时候直接 rm -rf venv 就好了。混用感觉是在自己挖坑跳呀


我只是想把 numpy、pandas、matplotlib 这些常用的库安装到主环境下,,然后把 jupyter 安装到虚拟环境 venv 下,,然后再虚拟环境 venv 下也能使用主环境下的 numpy、pandas、matplotlib,,

我想我这种用法还是比较常规的

之所以不把 jupyter 安装到主环境下,,是因为 jupyter 依赖好多好多包,,会导致 site-packages 目录下一堆不认识的东西,,,受不了

我在 D:\Python27 下安装了 Python
装完之后我启动 D:\Python27\venv

这是你文中的原话, 我不明白你为什么这么做.

正确的做法不应该是当你想要新做一个项目的时候:

$ mkdir new-project
$ cd new-project
$ virtualenv venv
$ source ./venv/bin/active

然后你 pip 安装了一堆第三方 lib 之后,

env$ pip freeze > requirements.txt

这个样子.

假设你把这个项目开源.

那么别人也可以下载了你的项目之后, 先构建一个虚拟环境, 然后在激活, 然后 pip install -r requirements.txt



原因我在 8 楼解释了

你的想法就是错误的.



virtualenv 的–system-site-packages 选项不就是为我这种用法设计的吗?

pipenv 路过

不太懂 lz 为什么不愿意在主环境和虚拟环境里把 numpy 什么的各装一份 难道是硬盘比较小?
说实话有的时候同一个包 在主环境和虚拟环境里需要的版本可能不一样 所以各装一份的好处是显而易见的

#9 最佳实践

你非要这么混着玩… 忠孝不两全,两头好处都想占,看起来很美,还是苦的自己。

pipenv 不行吧, 之前用过,不稳.

#16 有啥问题么?我手上做的都用它了

之前用过, 装第三方 lib, 装不下来. 然后就一直没用 pipenv 了.

回到顶部