在 Python 的项目中,如何管理所用的全部依赖库呢?最主流的做法是维护一份“requirements.txt”,记录下依赖库的名字及其版本号。

那么,如何来生成这份文件呢?在上篇文章《由浅入深:Python 中如何实现自动导入缺失的库?》中,我提到了一种常规的方法:

  1. pip freeze > requirements.txt

这种方法用起来方便,但有几点不足:

  • 它搜索依赖库的范围是全局环境,因此会把项目之外的库加入进来,造成冗余(一般是在虚拟环境中使用,但还是可能包含无关的依赖库)
  • 它只会记录以“pip install”方式安装的库
  • 它对依赖库之间的依赖关系不做区分
  • 它无法判断版本差异及循环依赖等情况
  • …………

可用于项目依赖管理的工具有很多,本文主要围绕与 requirements.txt 文件相关的、比较相似却又各具特色的 4 个三方库,简要介绍它们的使用方法,罗列一些显著的功能点。至于哪个是最好的管理方案呢?卖个关子,请往下看……

pipreqs

这是个很受欢迎的用于管理项目中依赖库的工具,可以用“pip install pipreqs”命令来安装。它的主要特点有:

  • 搜索依赖库的范围是基于目录的方式,很有针对性
  • 搜索的依据是脚本中所 import 的内容
  • 可以在未安装依赖库的环境上生成依赖文件
  • 查找软件包信息时,可以指定查询方式(只在本地查询、在 PyPi 查询、或者在自定义的 PyPi 服务)

基本的命令选项如下:

  1. Usage:
  2. pipreqs [options] <path>
  3. Options:
  4. --use-local Use ONLY local package info instead of querying PyPI
  5. --pypi-server <url> Use custom PyPi server
  6. --proxy <url> Use Proxy, parameter will be passed to requests library. You can also just set the
  7. environments parameter in your terminal:
  8. $ export HTTP_PROXY="http://10.10.1.10:3128"
  9. $ export HTTPS_PROXY="https://10.10.1.10:1080"
  10. --debug Print debug information
  11. --ignore <dirs>... Ignore extra directories
  12. --encoding <charset> Use encoding parameter for file open
  13. --savepath <file> Save the list of requirements in the given file
  14. --print Output the list of requirements in the standard output
  15. --force Overwrite existing requirements.txt
  16. --diff <file> Compare modules in requirements.txt to project imports.
  17. --clean <file> Clean up requirements.txt by removing modules that are not imported in project.

其中需注意,很可能遇到编码错误:UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in 。需要指定编码格式“--encoding=utf8”。

在已生成依赖文件“requirements.txt”的情况下,它可以强行覆盖、比对差异以及清除不再使用的依赖项。

pigar

pigar 同样可以根据项目路径来生成依赖文件,而且会列出依赖库在文件中哪些位置使用到了。这个功能充分利用了 requirements.txt 文件中的注释,可以提供很丰富的信息。

pigar 对于查询真实的导入源很有帮助,例如bs4 模块来自beautifulsoup4 库,MySQLdb 则来自于MySQL_Python 库。可以通过“-s”参数,查找真实的依赖库。

  1. $ pigar -s bs4 MySQLdb

它使用解析 AST 的方式,而非正则表达式的方式,可以很方便地从 exec/eval 的参数、文档字符串的文档测试中提取出依赖库。

另外,它对于不同 Python 版本的差异可以很好地支持。例如,concurrent.futures 是 Python 3.2+ 的标准库,而在之前早期版本中,需要安装三方库futures ,才能使用它。pigar 做到了有效地识别区分。(PS:pipreqs 也支持这个识别,详见这个合入:https://github.com/bndr/pipreqs/pull/80

pip-tools

pip-tools 包含一组管理项目依赖的工具:pip-compile 与 pip-sync,可以使用命令“pip install pip-tools”统一安装。它最大的优势是可以精准地控制项目的依赖库。

两个工具的用途及关系图如下:

pip-compile 命令主要用于生成依赖文件和升级依赖库,另外它可以支持 pip 的“Hash-Checking Mode ”,并支持在一个依赖文件中嵌套其它的依赖文件(例如,在 requirements.in 文件内,可以用“-c requirements.txt”方式,引入一个依赖文件)。

它可以根据 setup.py 文件来生成 requirements.txt,假如一个 Flask 项目的 setup.py 文件中写了“install_requires=['Flask']”,那么可以用命令来生成它的所有依赖:

  1. $ pip-compile
  2. #
  3. # This file is autogenerated by pip-compile
  4. # To update, run:
  5. #
  6. # pip-compile --output-file requirements.txt setup.py
  7. #
  8. click==6.7 # via flask
  9. flask==0.12.2
  10. itsdangerous==0.24 # via flask
  11. jinja2==2.9.6 # via flask
  12. markupsafe==1.0 # via jinja2
  13. werkzeug==0.12.2 # via flask

在不使用 setup.py 文件的情况下,可以创建“requirements.in”,在里面写入“Flask”,再执行“pip-compile requirements.in”,可以达到跟前面一样的效果。

pip-sync 命令可以根据 requirements.txt 文件,来对虚拟环境中进行安装、升级或卸载依赖库(注意:除了 setuptools、pip 和 pip-tools 之外)。这样可以有针对性且按需精简地管理虚拟环境中的依赖库。

另外,该命令可以将多个“*.txt”依赖文件归并成一个:

  1. $ pip-sync dev-requirements.txt requirements.txt

pipdeptree

它的主要用途是展示 Python 项目的依赖树,通过有层次的缩进格式,显示它们的依赖关系,不像前面那些工具只会生成扁平的并列关系。

除此之外,它还可以:

  • 生成普遍适用的 requirements.txt 文件
  • 逆向查找某个依赖库是怎么引入进来的
  • 提示出相互冲突的依赖库
  • 可以发现循环依赖,进行告警
  • 生成多种格式的依赖树文件(json、graph、pdf、png等等)

它也有缺点,比如无法穿透虚拟环境。如果要在虚拟环境中工作,必须在该虚拟环境中安装 pipdeptree。因为跨虚拟环境会出现重复或冲突等情况,因此需要限定虚拟环境。但是每个虚拟环境都安装一个 pipdeptree,还是挺让人难受的。

好啦,4 种库介绍完毕,它们的核心功能都是分析依赖库,生成 requirements.txt 文件,同时,它们又具有一些差异,补齐了传统的 pip 的某些不足。

本文不对它们作全面的测评,只是选取了一些主要特性进行介绍,好在它们安装方便(pip install xxx),使用也简单,感兴趣的同学不妨一试。

更多丰富的细节,请查阅官方文档:

https://github.com/bndr/pipreqs

https://github.com/damnever/pigar

https://github.com/jazzband/pip-tools

https://github.com/naiquevin/pipdeptree

公众号【Python猫】, 本号连载优质的系列文章,有喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写作、优质英文推荐与翻译等等,欢迎关注哦。

Python 依赖库管理哪家强?pipreqs、pigar、pip-tools、pipdeptree 任君挑选的更多相关文章

  1. 201806 数据处理 SQL、python、shell 哪家强...速度PK(上篇)

    最近在工作中,进行大量的数据处理,使用的是mysql5.7.22,发现当数据量级达到几十万之后,SQL执行速度明显变慢.尤其是当多个表join时,于是就尝试用python pandas进行数据处理,发 ...

  2. Python之虚拟环境virtualenv、pipreqs生成项目依赖第三方包

    virtualenv简介 含义: virtual:虚拟,env:environment环境的简写,所以virtualenv就是虚拟环境,顾名思义,就是虚拟出来的一个新环境,比如我们使用的虚拟机.doc ...

  3. 使用 pip wheel 实现 Python 依赖包的离线安装

    pip python 依赖 安装 有时候, 需要部署 Python 应用的服务器没有网络连接, 这时候, 你就要把整个 Python 应用做成离线安装包. 借助 wheel, 很容易就可以实现. 首先 ...

  4. python依赖包整体迁移方法(pip)

    做个记录 python依赖包整体迁移方法

  5. 【xlwings1】Python-Excel 模块哪家强

    Python-Excel 模块哪家强?   0. 前言 从网页爬下来的大量数据需要清洗? 成堆的科学实验数据需要导入 Excel 进行分析? 有成堆的表格等待统计? 作为人生苦短的 Python 程序 ...

  6. Python项目生成requirements.txt文件及pip升级问题解决及流程

    缘由:新项目使用Python, PC上的python包不全,需要通过requirements.txt文件指定安装所需包 pip安装遇到一些坑 一.直接使用pip包管理工具生成requirements. ...

  7. Pycharm使用教程(四)-安装python依赖包(非常详细,非常实用)

    简介 在做python开发时,需要很多依赖包,如果已经安装pip,安装依赖包,可以通过命令行:没有安装的,也可以通过PyCharm安装. 具体安装步骤 1.在File->Setting,如图: ...

  8. 最简单的方式离线部署Python依赖包

    最简单的方式离线部署Python依赖包 SHOW ME CODE! 打包: $ tempdir=$(mktemp -d /tmp/wheelhouse-XXXXX) $ pip wheel -r re ...

  9. [转]Python依赖打包发布详细

    Python依赖打包发布详细   http://www.cnblogs.com/mywolrd/p/4756005.html 将Python脚本打包成可执行文件   Python是一个脚本语言,被解释 ...

随机推荐

  1. 验证fstab文件修改是否正确

    /etc/fstab文件是系统启动时要挂载点文件系统. 如果fstab文件配置错误,会导致系统无法正常启动. 最近我就是因为大意,在配置fstab重启服务器后,出现系统无法识别挂载点/opt/back ...

  2. centos文件解压缩7z

    1.7z 安装 yum install p7zip 压缩test文件夹生成test.7z 7za a -t7z -r test.7z test #a 代表添加文件/文件夹到压缩包 -t 是指定压缩类型 ...

  3. 关于CDH集群spark的三种安装方式简述

    一.spark的命令行模式 1.第一种进入方式:执行 pyspark进入,执行exit()退出 注意报错信息:java.lang.IllegalArgumentException: Required ...

  4. 读《深入理解Elasticsearch》点滴-查询分类

    1.如何分类,略.个人不接受书中的分类方法,建议采用官网上的分类方法 2.term查询,可以模拟No-SQL数据库

  5. Ubuntu 查看操作系统的位数

    查看Ubuntu操作系统的位数是32位还是64位,可以通过以下命令来查看: getconf LONG_BIT 返回32或64 :如图

  6. 使用Hexo开源博客系统,轻松搭建你的个人博客(2)- 配置篇

    上一章节,我们介绍了Hexo的基础搭建,搭建完大家一定发现,是英文版本的,并且页面有点丑陋.这一章节,就来跟大家介绍Hexo的配置和主题的设置. 站点信息 上一章有跟大家提到过_config.yml这 ...

  7. IntelliJ IDEA 如何在同一个窗口创建多个项目--超详细教程

    一.IntelliJ IDEA与Eclipse的区别 二.在同一个窗口创建多个项目 1.打开IntelliJ IDEA,点击Create New Project 2.Java Enterprise-- ...

  8. 高效解决「SQLite」数据库并发访问安全问题,只这一篇就够了

    Concurrent database access 本文译自:https://dmytrodanylyk.com/articles/concurrent-database/ 对于 Android D ...

  9. Java 上传解压zip文件,并且解析文件里面的excel和图片

    需求:上传一个zip文件,zip文件里面包含一个excel和很多图片,需要把excel里面的信息解析出来保存到表中,同时图片也转化成base64保存到数据库表中. PS:为了方便不同水平的开发人员阅读 ...

  10. 【实战】 elasticsearch 写入速度提升的案例分享

    文章首发投稿至InfoQ,[侠梦的开发笔记]公众号,欢迎关注 https://www.infoq.cn/article/t7b52mbzxqkwrrdpVqD2 基本配置 基本配置,5台配置为 24C ...