Python版本管理及项目环境管理

前面有一篇文章是教大家如何使用VSCode, Python, Django来快速搭建一个后台应用,其中有讲到使用了pyenv来管理Python版本
使用VSCode+Python+Djagon快速搭建Restful Web Application
今天给大家带来这篇Python版本管理及项目环境管理文章,希望对大家有所帮助。

Python版本与项目环境

作为一名开发人员,你肯定会参与不同的项目,而不同的项目可能使用了不同版本的Python。另外,每一个项目都会依赖不同的库文件,并且我们需要在不同的项目之间进行切换?如果你的开发电脑,使用的是最新版本的Ubuntu 24,那么系统默认安装的Python3则是3.12.7,而在这之前开发的项目,很有可能使用的是3.11版本的Python,所以在开发的电脑上安装和管理不同版本的Python是很常见的。那么我们怎样在开发电脑上安装和管理不同版本的Python呢,又如何管理不同项目的Python库信赖?接下来我将一一解答。

两个工具( Pyenv + Pipenv )

我们需要用到两个工具来实现上面的需求

  • Pyenv:Python 版本管理工具
  • Pipenv:管理「依赖包(虚拟环境 + Requirements)」的工具

使用 Pyenv 管理多个 Python 版本

什么是Pyenv

Pyenv 是一个非常流行的 Python 版本管理工具,能够帮助你在同一台机器上安装、管理和切换多个 Python 版本。它的核心功能包括以下几个:

  • 安装任意版本的 Python
  • 通过 pyenv global, pyenv local, pyenv shell 等命令轻松切换全局、当前目录或当前会话使用的 Python 版本
  • 搭配插件 pipenv 更好地管理虚拟环境

Pyenv 主要支持 macOS 和 Linux。对于 Windows,可以使用第三方项目 pyenv-win,大家可自行摸索。

Pyenv 的基本使用

安装Pyenv

以Ubuntu为例,以下是具体的安装步骤:

第一步、更新系统,安装依赖库

arsenal@txzq1899:~$ sudo apt update
arsenal@txzq1899:~$ sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev \
liblzma-dev python3-openssl git

因为pyenv 是一个开源社区项目,而不是由官方 Python 或 Ubuntu 团队直接维护,且pyenv 的版本更新较快,APT 源的更新可能无法及时跟上,因此 pyenv 的开发者推荐直接使用官方仓库。所以在安装pyenv之前,先确保系统具有构建 Python 所需的依赖。

第二步、安装Pyenv

arsenal@txzq1899:~$ curl https://pyenv.run | bash

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   270  100   270    0     0    217      0  0:00:01  0:00:01 --:--:--   217
Cloning into '/home/arsenal/.pyenv'...
remote: Enumerating objects: 1332, done.
remote: Counting objects: 100% (1332/1332), done.
remote: Compressing objects: 100% (728/728), done.
remote: Total 1332 (delta 797), reused 780 (delta 471), pack-reused 0 (from 0)
Receiving objects: 100% (1332/1332), 1.13 MiB | 4.67 MiB/s, done.
Resolving deltas: 100% (797/797), done.
Cloning into '/home/arsenal/.pyenv/plugins/pyenv-doctor'...
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 11 (delta 1), reused 5 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (11/11), 38.72 KiB | 861.00 KiB/s, done.
Resolving deltas: 100% (1/1), done.
Cloning into '/home/arsenal/.pyenv/plugins/pyenv-update'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 10 (delta 1), reused 5 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (10/10), done.
Resolving deltas: 100% (1/1), done.
Cloning into '/home/arsenal/.pyenv/plugins/pyenv-virtualenv'...
remote: Enumerating objects: 64, done.
remote: Counting objects: 100% (64/64), done.
remote: Compressing objects: 100% (57/57), done.
remote: Total 64 (delta 10), reused 22 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (64/64), 43.08 KiB | 1.00 MiB/s, done.
Resolving deltas: 100% (10/10), done.

WARNING: seems you still have not added 'pyenv' to the load path.

# Load pyenv automatically by appending
# the following to 
# ~/.bash_profile if it exists, otherwise ~/.profile (for login shells)
# and ~/.bashrc (for interactive shells) :

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"

# Restart your shell for the changes to take effect.

# Load pyenv-virtualenv automatically by adding
# the following to ~/.bashrc:

eval "$(pyenv virtualenv-init -)"

第三步、配置.bashrc
修改~/.bashrc 文件,并重新加载.bashrc文件,这里需要注意一点,确保 pyenv的shims在PATH中优先

arsenal@txzq1899:~$ sudo vim .bashrc

#在.bashrc文件中增加如下三行:
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH"

eval "$(pyenv init -)"

#使.bashrc生效
arsenal@txzq1899:~$ source .bashrc

第四步、通过pyenv安装Python

arsenal@txzq1899:~$ pyenv install 3.11.11
Downloading Python-3.11.11.tar.xz...
-> https://www.python.org/ftp/python/3.11.11/Python-3.11.11.tar.xz
Installing Python-3.11.11...
Installed Python-3.11.11 to /home/arsenal/.pyenv/versions/3.11.11

#检查安装的Python
arsenal@txzq1899:~$ pyenv versions
* system (set by /home/arsenal/.pyenv/version)
  3.11.11
arsenal@txzq1899:~$ 

第五步、切换Python版本

#切换前先查看当前Python版本
arsenal@txzq1899:~$ python3 --version
Python 3.12.7

#切换Python版本,并检查Python版本
arsenal@txzq1899:~$ pyenv global 3.11.11
arsenal@txzq1899:~$ pyenv versions
  system
* 3.11.11 (set by /home/arsenal/.pyenv/version)

arsenal@txzq1899:~$ python3 --version
Python 3.11.11

到这里我们已经可以通过pyenv 来安装和管理不同版本的python了。

使用pipenv管理Python虚拟环境

Pipenv 的核心功能

  • 整合 Pip + Virtualenv
    Pipenv 可以理解为同时做了两件事:

    • 创建并管理虚拟环境(virtualenv),从而将项目的依赖与系统环境隔离。
    • 管理安装 Python 包依赖(相当于 pip + requirements.txt 的结合)。
  • 使用 Pipfile 和 Pipfile.lock
    Pipenv 引入了 Pipfile(类似 package.json)和 Pipfile.lock(类似 package-lock.json) 来记录依赖与锁定版本号。

    • Pipfile 里记录“你想要的依赖”;
    • Pipfile.lock 则精确锁定住当前安装的依赖版本,保证团队协作时环境一致。
    • 一个Pipfile样例:
      arsenal@txzq1899:~/Workspace/project-1$ cat Pipfile
      [[source]]
      url = "https://pypi.org/simple"
      verify_ssl = true
      name = "pypi"
      
      [packages]
      numpy = "*"
      simplejson = "*"
      dataclasses-json = "*"
      mysql-connector-python = "*"
      redis = "*"
      hiredis = "*"
      requests = "*"
      
      [dev-packages]
      
      [requires]
      python_version = "3.11"
      
  • 简化依赖管理

    • pipenv install requests:安装第三方库 requests,并自动更新 Pipfile/Pipfile.lock;
    • pipenv shell:启动/激活当前项目的虚拟环境;
    • pipenv run :在虚拟环境里执行某个命令。

安装 pipenv

pipenv 的安装则相对简单,只需要一条命令:

arsenal@txzq1899:~$ pip install pipenv
arsenal@txzq1899:~$ pipenv --version
pipenv, version 2024.4.1

使用 pipenv 创建虚拟环境

方式一、先激活,再安装依赖库

#激活虚拟环境
arsenal@txzq1899:~/Workspace/backend$ pipenv shell
Creating a virtualenv for this project
Pipfile: /home/arsenal/Workspace/backend/Pipfile
Using /home/arsenal/.pyenv/versions/3.11.11/bin/python3.11.11 to create virtualenv...
⠹ Creating virtual environment...created virtual environment CPython3.11.11.final.0-64 in 206ms
  creator CPython3Posix(dest=/home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/arsenal/.local/share/virtualenv)
    added seed packages: pip==24.3.1, setuptools==75.8.0, wheel==0.45.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_
Launching subshell in virtual environment...
 source /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_/bin/activate
arsenal@txzq1899:~/Workspace/backend$  source /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_/bin/activate

#安装项目依赖库
(backend) arsenal@txzq1899:~/Workspace/backend$ pipenv install
Installing dependencies from Pipfile.lock (41ecc3)...
(backend) arsenal@txzq1899:~/Workspace/backend$ 

方式二、通过pipenv sync创建虚拟环境

#创建虚拟环境,并安装依赖库
arsenal@txzq1899:~/Workspace/backend$ pipenv sync

Creating a virtualenv for this project
Pipfile: /home/arsenal/Workspace/backend/Pipfile
Using /home/arsenal/.pyenv/versions/3.11.11/bin/python3.11.11 to create virtualenv...
⠙ Creating virtual environment...created virtual environment CPython3.11.11.final.0-64 in 131ms
  creator CPython3Posix(dest=/home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/arsenal/.local/share/virtualenv)
    added seed packages: pip==24.3.1, setuptools==75.8.0, wheel==0.45.1
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

✔ Successfully created virtual environment!
Virtualenv location: /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock (41ecc3)...
All dependencies are now up-to-date!

#激活虚拟环境
arsenal@txzq1899:~/Workspace/backend$ pipenv shell

Launching subshell in virtual environment...
 source /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_/bin/activate
arsenal@txzq1899:~/Workspace/backend$  source /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_/bin/activate
(backend) arsenal@txzq1899:~/Workspace/backend$

两种方式都可以,没有什么区别,只是顺序不一样。

解决pipenv sync/install 卡住不动的问题

在安装项目依赖的时候,有一点需要注意,大家可能会在安装依赖库的时候卡在下面的环节,等了很久,也没有动静。

Installing dependencies from Pipfile.lock (41ecc3)...

其实这种情况大概率是因为国内在下载某一个依赖库的时候由于网络的原因导致无法下载,有如下的方式可以查看具体的过程。

查看安装过程

#通过增加 -v 参数(或者:--verbose),来显示详细过程
arsenal@txzq1899:~/Workspace/backend$ pipenv sync -v
......此处省略安装过程......

这样我们就能够知道pipenv install 或者 pipenv sync 具体的执行过程。

使用国内镜像

此外,如果网络环境不好,可以使用pypi-mirror来指定使用国内的镜像服务器来下载依赖库

arsenal@txzq1899:~/Workspace/backend$ pipenv sync --pypi-mirror https://pypi.tuna.tsinghua.edu.cn/simple -v

......此处省略安装过程......

arsenal@txzq1899:~/Workspace/backend$ pipenv shell
Launching subshell in virtual environment...
 source /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_/bin/activate
arsenal@txzq1899:~/Workspace/backend$  source /home/arsenal/.local/share/virtualenvs/backend-GHBtKpl_/bin/activate
(backend) arsenal@txzq1899:~/Workspace/backend$ 

关注我的公众号

欢迎大家关注、点赞、转发,一起交流软件开发、架构设计、云原生技术。
TXZQ聊IT技术与架构