Python-包管理器(pipenv)

前言

一般我们都是使用pip安装三方库,用起来很方便。但是所有项目的依赖都在一个环境中。

如果我们要把项目部署到服务器上面的话,就稍微有些麻烦了,因为还需要在服务器上用pip安装这些包,假如项目中用到很多包的话,一个个安装会很麻烦,而且没有通用性。

Java上的maven、gradle,NodeJS的npm这些工具就不存在这个问题,它们有一个或多个的专门的依赖文件来管理这些包。

pipenv就是这样一个类似的工具,可以帮助我们管理Python和第三方库的版本。

pipenv

安装pipenv

1
pip install pipenv

初始化

项目根目录运行

1
pipenv install

这样会在项目中创建一个名为Pipfile的文件,文件内容类似下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
[[source]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
verify_ssl = true
name = "tsinghua"

[packages]
requests = "*"

[dev-packages]

[requires]
python_version = "3.8"

其中[packages]是项目依赖,也就是项目运行所需要的依赖,[dev-packages]是开发依赖,是我们项目运行时不需要但是开发过程中需要的依赖。

添加依赖

1
pipenv install requests

或者指定版本

1
pipenv install requests==2.13.0

默认安装的是项目依赖,要安装开发依赖就添加参数-d--dev

比如

1
2
3
pipenv install requests==2.13.0 -d
# 或者
pipenv install requests==2.13.0 --dev

卸载依赖

1
pipenv uninstall requests

和添加依赖不同,如果项目依赖和开发依赖拥有同一个库,那么只要运行卸载,会同时卸载项目依赖和开发依赖,并且配置文件中也会删除。

卸载所有的包

这个会同时卸载所有项目依赖和开发依赖,但是配置文件中不会删除相应配置。

1
pipenv uninstall --all

卸载所有的开发包

这个会卸载所有开发依赖,但是配置文件中不会删除相应配置。

1
pipenv uninstall --all-dev

安装依赖

安装所有配置文件中的依赖

1
pipenv install

更新

查看所有需要更新的包:

1
pipenv update --outdated

更新所有包:

1
pipenv update

更新指定的包:

1
pipenv update <包名>

依赖导入

如果项目中有requirements.txt文件,pipenv会在安装的时候自动导入。如果需要导入其他位置的requirements.txt,可以用下面的命令:

1
pipenv install -r path/to/requirements.txt

指定Python版本

如果不指定版本号,pipenv会使用系统默认的Python版本。

pipenv会创建虚拟Python环境,并在其中用pip安装所有包。如果要指定Python版本,可以用下面的命令,三种版本号都支持:

1
2
3
pipenv --python 3
pipenv --python 3.6
pipenv --python 2.7.14

需要注意,这里指定的Python必须是系统已经安装的、可以在环境变量中搜索到的版本号,如果指定未安装的版本,会提示错误。

运行命令

用下面的命令可以启动一个在虚拟环境中的shell:

1
pipenv shell

如果不想启动shell,而是直接在虚拟环境中执行命令,可以使用run:

1
pipenv run python --version

自动安装Python

pipenv只能搜索系统中已经安装的Python版本,对于未安装的版本,会提示错误。但是如果你同时安装了pyenv的话,pipenv会自动发现pyenv,然后直接询问你是否要安装。

这样一来,原来的工作流程是:用pyenv安装某个Python->用virtualenv或venv创建虚拟环境->用pip从requirements.txt中安装包->将来可能还要更新包。现在完全可以用pipenv一两条命令解决,真的是非常方便。

自动加载.env文件

.env文件可以设置一些环境变量,在程序开发的时候模拟环境变量。pipenv也可以自动加载.env文件。

1
2
3
4
5
6
7
8
9
10
11
$ cat .env
HELLO=WORLD

$ pipenv run python
Loading .env environment variables…
Python 2.7.13 (default, Jul 18 2017, 09:17:00)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['HELLO']
'WORLD'

环境变量支持

Pipfile中也可以引用环境变量的值,格式为${MY_ENVAR}$MY_ENVAR,在Windows系统中还支持%MY_ENVAR%

1
2
3
4
5
6
7
8
9
10
11
[[source]]
url = "https://${PYPI_USERNAME}:${PYPI_PASSWORD}@my_private_repo.example.com/simple"
verify_ssl = true
name = "pypi"

[dev-packages]

[packages]
requests = {version="*", index="home"}
maya = {version="*", index="pypi"}
records = "*"

自定义虚拟环境路径

很多工具遵循Linux开发习惯,将东西全存在用户目录中,在Linux中可能没啥,但是在Windows下可能有人不喜欢把这些东西放在用户目录。当然pipenv也可以自定义,只需要设置或修改WORKON_HOME环境变量的值即可。

如果设置了PIPENV_VENV_IN_PROJECT环境变量,pipenv会把虚拟环境放在项目目录的.venv目录下。

从setup.py安装

pipenv也可以从setup.py安装:

1
pipenv install -e .

那么为什么不全用pipenv来安装呢?官方文档这里为我们做出了解释:项目可以分为两种,程序和库,对于程序来说应该使用pipenv,而对于库来说则是在setup.py中安装。

virtualenv

上面所说的pipenv,实际上就是依赖于virtualenv,我建议使用pipenv

因为virtualenv有以下几个问题

  • 导出依赖的时候也会导出依赖的依赖,这样依赖就会比较杂乱。
  • 不能区分项目依赖和开发依赖。
  • 使用不方便,每次部署前要先导出,然后在部署环境导入。

通过 virtualenv 来给每个项目独立创建包管理环境,并且可以独立出 Python 的运行环境。

  • virtualenv就是一个搭建虚拟化的python环境,便于不同的项目在同一台机器上开发运行。
  • 在生产环境中还是使用docker给不同的项目创建不同的容器,各自分开运行为好,不宜放在一个单独的物理机中运行。

安装依赖

1
pip install virtualenv

项目目录下运行

1
virtualenv venv

激活

1
.\venv\Scripts\activate.bat

一旦进入到虚拟环境中,安装、卸载库都是在这个虚拟环境中,不会影响到其他环境

退出

1
.\venv\Scripts\deactivate.bat

此时还需将当前工程的interpreter改为当前的虚拟环境,要不然会不起作用。

PyCharm中设置

File=>Settings

搜索Python Interpreter

image-20211129135707458

image-20211129135814066

依赖导出导入

项目下运行一下命令导出依赖

1
pip freeze > requirements.txt

在待部署机器上,使用以下命令安装就可以恢复依赖环境:

1
pip install -r requirements.txt