开发随笔——pipenv创建虚拟环境时常见问题
背景
本文基于本人在Ubuntu22.04中通过pipenv创建虚拟环境以运行Django项目时遇到的问题编写
版本不匹配
报错信息
AttributeError: module 'collections' has no attribute 'MutableMapping'
原因
这个错误 AttributeError: module 'collections' has no attribute 'MutableMapping'
通常发生在 Python 3.10 及以上版本中,因为从 Python 3.10 开始,collections.MutableMapping
已经被移到了 collections.abc
模块中。
这个问题的原因有两个可能性:
- 本人使用的Ubuntu22.04预装了Python3.10,但是将要创建的Pipenv虚拟环境使用的是Python3.9,因此发生了冲突
- 安装的Pipenv版本过低,因此在尝试读取错误的文件
解决方案
1.降低Python版本
对于第一个可能性,最好的方案就是降低Python版本到3.10以下。
步骤 1: 卸载Python 3.10
首先,你需要卸载当前的Python 3.10版本。在Ubuntu上,你不应该直接卸载Python,因为系统依赖于它。相反,你可以安装一个特定的旧版本,并使用update-alternatives
来管理不同版本。
步骤 2: 安装Python 3.9
你可以从DEADSNAKES PPA安装特定版本的Python。DEADSNAKES PPA提供了多个Python版本的包。
sudo add-apt-repository ppa:deadsnakes/ppa
# 添加DEADSNAKES PPA
sudo apt update
# 更新包列表
sudo apt install python3.9
# 安装Python 3.9
步骤 3: 设置Python 3.9为默认版本
如果你想要将Python 3.9设置为默认版本,可以使用update-alternatives
工具:
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 2
# 更新update-alternatives的链接
sudo update-alternatives --config python3
# 选择默认版本
然后选择Python 3.9对应的选项。
2.获取更高版本的Pipenv
Do not install pipenv from apt, it’s way too old. Install from pypi.
——AttributeError: module ‘collections’ has no attribute ‘MutableMapping’ · Issue #5469 · pypa/pipenv
来自Ubuntu22.04的搞笑反馈,apt中安装的Pipenv是版本过低的,此时需要使用pip install pipenv
卸载通过APT安装的Pipenv
sudo apt-get remove pipenv
你也可以选择卸载Pipenv及其所有依赖项,但通常不建议这样做,除非你确定不再需要这些依赖项:
sudo apt-get purge pipenv
更新APT缓存以清除任何过时的信息:
sudo apt-get update
使用PyPI安装Pipenv
确保你已经安装了Python和pip。如果没有,可以使用以下命令安装:
sudo apt-get install python3 python3-pip
使用pip安装Pipenv。建议使用用户级别的安装,以避免需要sudo权限:
pip3 install --user pipenv
安装完成后,你可以通过以下命令验证Pipenv是否安装成功:
pipenv --version
如果你想在全局范围内使用Pipenv,可以将用户级别的bin目录添加到你的PATH环境变量中。这通常在~/.profile
或~/.bashrc
文件中完成。添加以下行:
export PATH="$HOME/.local/bin:$PATH"
然后,重新加载你的配置文件或重启终端:
source ~/.bashrc
注意!!!
如果你遇到了如下错误,
$ pipenv --version
-bash: /usr/bin/pipenv: No such file or directory
这表示你没有通过.bashrc
成功导入pip安装的包,重新导入下就好了。
以及,如果用了第一部分的解决方案,可能你在此时会报错apt-pkg的错误(如下),这时候切回去Python3.10就可以了,唉,沟槽的Ubuntu
Traceback (most recent call last):
File "/usr/lib/cnf-update-db", line 3, in <module>
import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'
distutils缺失
报错信息
ModuleNotFoundError: No module named 'distutils.cmd'
原因
这个错误原因我并不确定,因此只提供我个人的一个猜测。
跟据错误信息不难确定问题出于找不到distutils
,因此我们需要尝试手动安装该包。
但是!如果你是直接使用pipenv install
创建虚拟环境,有可能会出现安装后依旧报错的情况。
其主要是因为Ubuntu系统内的Python版本和Pipenv中的Python版本不同导致的,我也不确定版本相同是否还会出这个问题。
这一点在我不断尝试后发现,会报该错误其实不是Ubuntu系统内的Python在报错,实际上是创建虚拟环境后,虚拟环境中运行pip install
的时候报的错。
通过pipenv shell
进入虚拟环境的终端后直接使用pip install
可以发现依旧报错。
修复方案
首先,尝试一下能否直接通过安装distutils
解决问题
$ sudo apt-get update
······
$ sudo apt-get install python3-distutils
······
# 还可以尝试下指定版本的distutils
# sudo apt-get install python<版本号,如3.10>-distutils
# 通过以下代码可以查看版本是否正确
$ apt-cache policy python3-distutils
python3-distutils:
Installed: 3.10.8-1~22.04
Candidate: 3.10.8-1~22.04
Version table:
*** 3.10.8-1~22.04 500
500 http://mirrors.cloud.aliyuncs.com/ubuntu jammy-updates/main amd64 Packages
500 http://mirrors.cloud.aliyuncs.com/ubuntu jammy-security/main amd64 Packages
100 /var/lib/dpkg/status
3.10.4-0ubuntu1 500
500 http://mirrors.cloud.aliyuncs.com/ubuntu jammy/main amd64 Packages
其次,如果你的Python版本是3.12及以上,可能会遇到没有 distutils
的情况。可以通过安装 setuptools
来间接解决这一问题,因为 setuptools
依赖于 distutils
:
$ pip install setuptools
如果此时依旧报错,就进入Pipenv终端手动安装
$ pipenv shell
$ (pipenv) apt-get install pip
······
$ (pipenv) apt-get install python3-distutils
······
$ pip list
Package Version
---------- -------
pip 25.0.1
setuptools 75.8.0
wheel 0.45.1
此时退出虚拟环境后再调用pipenv install
即可
$ pipenv install
Loading .env environment variables...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock (e235b7)...
$ pipenv shell
Loading .env environment variables...
Launching subshell in virtual environment...
$ pip list
Package Version
-------------------- -----------
amqp 5.2.0
argon2-cffi 23.1.0
argon2-cffi-bindings 21.2.0
asgiref 3.8.1
billiard 4.2.1
boto3 1.35.56
······