Python 依赖库太多了该如何管理


Posted in Python onNovember 08, 2019

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

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

pip freeze 
>
 requirements
.
txt

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

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

…………

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

pipreqs

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

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

基本的命令选项如下:

Usage
:

 pipreqs 
[
options
]
 
<path>



Options
:

 
--
use
-
local
   
Use
 ONLY 
local
 
package
 info instead of querying 
PyPI

 
--
pypi
-
server 
<url>
 
Use
 custom 
PyPi
 server

 
--
proxy 
<url>
   
Use
 
Proxy
,
 parameter will be passed to requests library
.
 
You
 can also just 
set
 the

       environments parameter 
in
 your terminal
:

       $ 
export
 HTTP_PROXY
=
"http://10.10.1.10:3128"

       $ 
export
 HTTPS_PROXY
=
"https://10.10.1.10:1080"

 
--
debug    
Print
 debug information

 
--
ignore 
<dirs>
...
 
Ignore
 extra directories

 
--
encoding 
<charset>
 
Use
 encoding parameter 
for
 file open

 
--
savepath 
<file>
  
Save
 the list of requirements 
in
 the given file

 
--
print
    
Output
 the list of requirements 
in
 the standard output

 
--
force    
Overwrite
 existing requirements
.
txt

 
--
diff 
<file>
   
Compare
 modules 
in
 requirements
.
txt to project imports
.

 
--
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 文件中的注释,可以提供很丰富的信息。

Python 依赖库太多了该如何管理

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

$ 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”统一安装。它最大的优势是可以精准地控制项目的依赖库。

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

Python 依赖库太多了该如何管理

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

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

$ pip
-
compile
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file requirements.txt setup.py
#
click
==
6.7
# via flask
flask
==
0.12
.
2
itsdangerous
==
0.24
# via flask
jinja2
==
2.9
.
6
# via flask
markupsafe
==
1.0
# via jinja2
werkzeug
==
0.12
.
2
# via flask

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

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

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

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

pipdeptree

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

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让图片按照exif信息里的创建时间进行排序的方法
Mar 16 Python
python中logging包的使用总结
Feb 28 Python
Python实现针对给定字符串寻找最长非重复子串的方法
Apr 21 Python
解决pycharm的Python console不能调试当前程序的问题
Jan 20 Python
关于python字符串方法分类详解
Aug 20 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
Dec 03 Python
python itsdangerous模块的具体使用方法
Feb 17 Python
Python 读取有公式cell的结果内容实例方法
Feb 17 Python
python实现logistic分类算法代码
Feb 28 Python
keras使用Sequence类调用大规模数据集进行训练的实现
Jun 22 Python
Python爬虫基础之初次使用scrapy爬虫实例
Jun 26 Python
Python用any()函数检查字符串中的字母以及如何使用all()函数
Apr 14 Python
python+OpenCV实现车牌号码识别
Nov 08 #Python
python实现飞机大战小游戏
Nov 08 #Python
python 基于dlib库的人脸检测的实现
Nov 08 #Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
Nov 08 #Python
python实现身份证实名认证的方法实例
Nov 08 #Python
Python Django框架模板渲染功能示例
Nov 08 #Python
Python Django中间件,中间件函数,全局异常处理操作示例
Nov 08 #Python
You might like
SONY ICF-SW07收音机电路分析
2021/03/02 无线电
咖啡因含量是由谁决定的?低因咖啡怎么来?低因咖啡适合什么人喝
2021/03/06 新手入门
php调用mysql存储过程
2007/02/14 PHP
THINKPHP项目开发中的日志记录实例分析
2014/12/01 PHP
PHP生成随机数的方法实例分析
2015/01/22 PHP
PHP实现的json类实例
2015/07/28 PHP
PHP操作FTP类 (上传、下载、移动、创建等)
2016/03/31 PHP
javaScript复制功能调用实现方案
2012/12/13 Javascript
jquery简单瀑布流实现原理及ie8下测试代码
2013/01/23 Javascript
jQuery简单图表peity.js使用示例
2014/05/02 Javascript
chrome下jq width()方法取值为0的解决方法
2014/05/26 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
jQuery前端开发35个小技巧
2016/05/24 Javascript
瀑布流的实现方式(原生js+jquery+css3)
2020/06/28 Javascript
koa上传excel文件并解析的实现方法
2018/08/09 Javascript
在iFrame子页面里实现模态框的方法
2018/08/17 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
2018/12/20 Javascript
详解ES6 Promise的生命周期和创建
2019/08/18 Javascript
基于node+vue实现简单的WebSocket聊天功能
2020/02/01 Javascript
element中table高度自适应的实现
2020/10/21 Javascript
[57:38]2018DOTA2亚洲邀请赛3月30日 小组赛A组 OpTic VS OG
2018/03/31 DOTA
[38:39]KG vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
pycharm中显示CSS提示的知识点总结
2019/07/29 Python
Python序列对象与String类型内置方法详解
2019/10/22 Python
DJango的创建和使用详解(默认数据库sqlite3)
2019/11/18 Python
python常用数据重复项处理方法
2019/11/22 Python
python如何将两张图片生成为全景图片
2020/03/05 Python
Python多个装饰器的调用顺序实例解析
2020/05/22 Python
Python调用C语言程序方法解析
2020/07/07 Python
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
J2EE是技术还是平台还是框架
2016/08/14 面试题
二年级小学生评语
2014/04/21 职场文书
质量月口号
2014/06/20 职场文书
2015年建筑工程工作总结
2015/05/13 职场文书
婚宴致辞
2015/07/28 职场文书
python中requests库+xpath+lxml简单使用
2021/04/29 Python