如何解决Python包依赖问题

以简洁高效(指编程较为高效, 而不是运行速度)出名的Python, 在包依赖问题上有时候让人挠头.

一些新手复制了Github上的项目准备运行, 很多时候会在包依赖这一步上卡个半天.(这里推荐新手最好在基于Linux的系统或者Mac上, 一些包比如Scrapy的Win32相关依赖可能无法直接通过包管理工具安装, 会让新手从入门到放弃). 其他涉及到项目需要到其他机器部署时, 也会遇到包依赖问题.

# 这可能是部署过程中最常见的错误
ModuleNotFoundError: No Module named 'XXX'

通过pip输出依赖

pip freeze > requirements.txt

这个命令可能是很多同学用来输出依赖的命令, 但它输出的是当前环境下(

笔者默认你使用的是Python的虚拟环境)的所有包, 也就是输出当前你安装的全部非Python标准库包)

笔者在自己终端上试了一下, 输出的文件如下: (这里暴露了我没有按项目建虚拟环境的烂习惯(逃)

# 省略N个库
....
Django==1.11.8
django-mongonaut==0.2.21
docopt==0.6.2
Flask==0.10.1
Flask-Bootstrap==3.0.3.1
Flask-Login==0.3.1
Flask-Mail==0.9.0
Flask-Migrate==1.1.0
Flask-Moment==0.2.1
Flask-PageDown==0.1.4
Flask-Script==0.6.6
Flask-SQLAlchemy==1.0
Flask-WTF==0.9.4
ForgeryPy==0.1
html5lib==1.0b3
hyperlink==17.3.1
idna==2.6
incremental==17.5.0
itsdangerous==0.23
Jinja2==2.7.1
lxml==4.1.1
Mako==0.9.1
Markdown==2.3.1
MarkupSafe==0.18
mongoengine==0.9.0
numpy==1.14.0
pandas==0.22.0
parsel==1.3.1
pdfkit==0.6.1
pipreqs==0.4.9
pyasn1==0.4.2
pyasn1-modules==0.2.1
pycparser==2.18
PyDispatcher==2.0.5
pymongo==2.8
PyMySQL==0.7.9
pyOpenSSL==17.5.0
python-dateutil==2.6.1
pytz==2017.3
queuelib==1.4.2
requests==2.18.4
requests-file==1.4.3
scrape==0.9.12
Scrapy==1.5.0
...
# 省略N+1个库

对于按项目建环境的同学, 这种输出方式是没有多大问题的

只要部署的时候在终端键入pip install -r requirements.txt就可以安装好依赖了, 但是对于没有严格区分项目环境的同学, 一次性安装了其他的包, 并不是一个好的解决方案.

通过pipreqs库输出依赖

如这个库的名称所示, 就是为了方便管理依赖而生.

与pip直接导出全部不同, pipreqs只导出指定项目下Python文件import的库

用法如下

# 安装
pip install pipreqs
# 切换到项目目录
# 输出requirements.txt到项目根目录下
pipreqs --use-local ./

这里我切换到一个Django项目目录下, 打开requirements.txt, 内容是:

pandas==0.22.0
django_debug_toolbar.egg==info
mongoengine==0.9.0
Django==1.11.8

瞬间清爽不少.

通过Pipenv管理依赖

Pipenv, 汇集了Pip,Pipfile和Virtualenv的功能,是一个强大的命令行工具。

这里展示最简单的用法

  1. pip install pipenv安装好库.requirements.txt found, instead of Pipfile! Converting… Warning: Your Pipfile now contains pinned versions, if your requirements.txt did. We recommend updating your Pipfile to specify the "*" version, instead. ...上面的输出意思是: 找到了requirements.txt, 但不是Pipfile, 正在转换... Pipefile现在将包含固定版本信息, 如果你的requirements.txt中已包含. 我们推荐升级你的Pipefile到指定版本...
  2. 切换到项目根目录
  3. 终端键入Pipenv install如果你尚未建立requirements.txt那么将会得到一个空白的Pipfile文本文件, 此时我们在命令行中使用pipenv install 包名, 会在Pipefile写入对应包信息, 之后用户要安装依赖时, 使用pipenv install即可. 如果你已经建立, 终端上会输出以下信息:

输出Pipenv文件, 得到以下内容:

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
mongoengine = "==0.9.0"
"django-debug-toolbar.egg" = "==info"
django = "==1.11.8"
pandas = "==0.22.0"

[dev-packages]

[requires]
python_version = "3.6"

可以清楚的看到整个文件结构, 第一个是source是安装库所在源, 第二个是依赖库的信息, 第三个是当你开发环境所需要的包, 最后一个是Python版本.

当你需要区分开发环境和正式版本发布环境时, 可以使用以下命令:

pipenv install --dev 包名

如果正式版本发布时, 键入Pipenv install, 将不会安装dev标记的包

除非其他开发人员键入Pipenv install -dev, 才会安装所有包.


邮箱: fesonx@foxmail.com

公众号: 程序员的碎碎念

欢迎关注我的腾讯云

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏全栈工程师成长之路

深入浅出学习前端开发(环境搭建篇)

这里筑梦师,是一名正在努力学习的iOS开发工程师,目前致力于全栈方向的学习,希望可以和大家一起交流技术,共同进步,用简书记录下自己的学习历程.

710140
来自专栏渠道合作伙伴技术圈

Windows server环境下混合云部署DFS文件服务

很多传统企业在设计身份验证和文件服务时,都会使用微软的活动目录和windows server自带的文件共享来实现以上的需求, 公有云的出现给这个场...

891160
来自专栏java技术学习之道

常见的Redis面试题及分布式集群讲解

42470
来自专栏DT乱“码”

原 如何保障数据库的高可用

23920
来自专栏项勇

[Android笔记9]使用wifi连接adb打印数据

20950
来自专栏安智客

Android 8.0 中的安全增强功能

每个 Android 版本中都包含数十种用于保护用户的安全增强功能。以下是 Android 8.0 中提供的一些主要安全增强功能: 加密:在工作资料中增加了对...

255100
来自专栏逸鹏说道

怎么添加用户到sudo用户组

跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 前段时间用Ubuntu的sudo用惯了...

342100
来自专栏JAVA高级架构

Redis面试题及分布式集群

29910
来自专栏编程

浅析同步异步阻塞非阻塞

? 先说说这几个词的意思 同步:同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成。 异步:异步是不需要等待被依赖...

23280
来自专栏同步博客

搭建MySQL高可用负载均衡集群

  使用MySQL时随着时间的增长,用户量以及数据量的逐渐增加,访问量更是剧增,最终将会使MySQL达到某个瓶颈,那么MySQL的性能将会大大降低。这一结果也不...

42360

扫码关注云+社区

领取腾讯云代金券