Python包管理工具小结
此文已由作者张耕源授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
作为一名接触Python有一段时间的初学者,越来越体会到Python的方便之处,它使人能更
多的关注业务本身的逻辑,而不用太纠结语言层面的技巧与细节。然而,随着服务的规模
变得越来越大,如何方便快速地制作与发布一个Python软件包则越来越成为一个让人头疼
地问题,特别是像Openstack这种相对复杂、各种依赖也很多的Python项目,到目前也没有
发现特别完美的解决方案。这里将尝试对Python的包管理工具做一个小结,为将来更好的
解决这个问题提供思路。
setuptools
setuptools1 是Python提供的最基本的包管理工具,后面提到的其他更高层次的Python
包管理工具都是在它的基础上实现的。曾经Python还有其他各种各样类似功能的包管理工
具,比如distribute、distutils等等,对有选择困难症的同学非常不友好,不过目前绝大
多数Python项目都开始统一使用setuptools,其他工具已经被慢慢合并/遗弃了。
setuptools的常见使用方式是在Python项目中新建一个setup.py:
from setuptools import setup, find_packagessetup(
name = "HelloWorld",
version = "0.1",
packages = find_packages("helloworld"),
)
在这个文件中通过setuptools提供的各种关键字描述项目的元信息,包括名字、版本、
文件等等。写好后就可以通过python setup.py [command]执行setuptools提供的各种子
命令,比如编译、安装、测试、制作各种格式的软件安装包等等。
当你拿到一份Python项目的源代码,如果它已经写好了setup.py,你就可以方便的通过
setuptools将它安装到系统:
$ python setup.py install
目前,使用setuptools制作的软件安装包常见格式有:
source distro
$ python setup.py sdist
binary distro: egg
$ python setup.py bdist_egg
binary distro: wheel
$ python setup.py bdist_wheel
以openstack/nova为例,对应的三种格式软件安装包分别为:
nova-12.0.0.0b2.dev251.tar.gz
nova-12.0.0.0b2.dev251-py2.7.egg
nova-12.0.0.0b2.dev251-py2.py3-none-any.whl
sdist和wheel格式的安装包都可以使用最常见的pip命令安装,egg还只能通过
比较老得easy_install命令安装。
$ pip install nova-12.0.0.0b2.dev251.tar.gz$ easy_install nova-12.0.0.0b2.dev251-py2.7.egg$ pip install nova-12.0.0.0b2.dev251-py2.py3-none-any.whl
pbr
从上面的例子里可以看到,setup.py本质上还是一个Python脚本,有诸多语法的限制。
当Python项目比较庞大和复杂时,setup.py就会变的非常难写与维护。
在Openstack中,新建了一个pbr2 项目来处理这个问题。通过使用pbr项目提供的维护与setup.py对应的setup.cfg文本配置文件来自动生成setup.py从而解决这个问题。
比如上面的例子,切换到pbr就会变成这样:
setup.py
from setuptools import setupsetup(
setup_requires=['pbr'],
pbr=True,
)
setup.cfg
[metadata]name = HelloWorldversion = 0.1 [files]packages =
helloworld
当然,实际工程中,setup.cfg文件的内容会比这个例子复杂很多。
pip
setuptools解决了Python软件包的制作问题,那如何分发它们呢?Python本身提供了PyPI
基础设施与相应的pip3 命令行工具来做这件事。
你可以将生成好的软件包通过
$ python setup.py upload
通过网络上传到PyPI。
上传成功后,其他人就可以直接通过pip命令安装你上传的软件包:
$ pip install ${package_name}
virtualenv
提到了pip,就不得不提一下virtualenv4 ,这两个工具经常是在一起搭配使用的。
virtualenv的功能有点像Linux系统下的chroot命令,运行
$ virtualenv .venv
后,他会将最小安装一个Python运行环境到当前目录的.venv文件夹,内容包括.venv/bin
下的python、pip命令,.venv/lib下的python库目录等等。当你使用
$ . .venv/bin/activate
激活刚刚创建出来的这个virtualenv环境后,你执行的python相关的二进制命令其实都是
.venv/bin目录下(而不是系统路径下的),安装/引用的python库也都是在.venv/lib目录
下的。
这样子,使用virtualenv后可以让每个Python项目使用独立的Python运行环境,不会产生
几个项目间依赖冲突、污染操作系统Python库的问题。
wheel
wheel5 是众多Python软件安装包格式的一种,这里专门要把它单独拿出来说是因为它的
优点和好处确实很多,是Python官方推荐的新一代Python项目发布格式,个人也非常希望
目前所有PyPI上项目都能尽快提供wheel格式的安装包。新版本的pip已经可以直接从PyPI
上下载安装wheel格式的安装包了。
和老的egg6 格式相比,wheel能让人直观感受到的先进之处:
不包含.pyc文件(预编译的.pyc文件偶尔会导致各种奇怪的问题,我们更希望他能在
每次安装时在本地生成更新),当项目是纯Python项目时wheel和source distro基本
没有什么区别。官方支持,pip命令可以直接安装wheel,但是不能处理egg。
更丰富的软件包元信息,甚至包中的每个文件都有版本记录。
更细致的包命名规则
和egg格式一样,wheel拥有的优点:
单安装文件。你是希望从源码文件夹下执行一系列命令编译安装一个Python项目,还是
直接通过一个文件安装呢?依赖处理。安装程序会帮你自动安装相关依赖的Python库。
二进制发布格式。当项目包含需要编译生成的extension时,可以将编译好的
.so/.dylib/.dll等动态链接库直接一并打包,实现“一次编译,到处运行”(在相同的
平台上)的效果,而不是每次都在终端重新编译生成。这点在大规模服务器上批量部署
Python程序项目非常重要。可惜的是,目前wheel仅在windows和mac os平台支持这个特
性,Linux平台由于各种原因还不支持,希望PyPA能尽快解决吧。
这里有一份官方文档详细比较了wheel和egg: 7
Linux distros
上面总结了Python打包社区PyPA(Python Packaging Authority)本身提供的各种工具,
但是在各个Linux发行版中,出于和系统集成(比如各种配置文件、脚本的管理)、加强
包的管理(PyPI上的软件包都是开发者自行自由上传的)等等原因,很多Linux发行版通常
也会制作维护各自平台上专有的Python项目安装包,比如Debian系的.deb格式安装包
等等。
由于各个Linux发行版的管理风格、系统路径、甚至默认的Python版本等等都大相径庭,
所以各种安装包的规格、内容也差别很大。
常见的Linux发行版里,Debian系的.deb格式和Redhat系的.rpm格式安装包属于比较严格和
保守的一派。它们通常会做严格的版本、依赖控制;维护项目相关的服务配置文件、
SysVinit/systemd、syslog、logrotate脚本等等;安装包会包含任何需要编译的二进制
文件(如.pyc文件、各种需要编译的c extension等),不需要在安装时进行本地编译;
使用Python2作为Python的默认版本,甚至在某些较老的Debian、CentOS的发行版中,
还在使用Python2.6/2.3。
而像ArchLinux这样比较激进的Linux发行版,安装包的管理就非常奔放。安装包通常只是
帮你指定一下依赖、任何软件和库都用最新版本(非常令人讨厌的,Python也默认使用
Python3)、Python项目的PKGBUILD里package()通常就一行
“python2 setup.py install ...”。
总结
上面基本把最近自己接触到的和Python相关的包管理工具介绍了一遍,而在实际操作中去
在服务器上批量发布部署Python项目,利用上面提到的这些工具,能想到的通常有下面
几种方式。
每次到这个时候,真的是非常羡慕Java/Go这些不用纠结这种问题的编程语言。
直接源码安装
适合在自己的开发调试机器上瞎搞的时候使用。
由于Python/pip本身的包管理功能比较弱,直接在服务器上用这种方法会给服务器的系统
安装一系列不可控制的Python依赖,并且可能破坏其他Python程序的依赖,导致其他
Python程序无法正常运行。装的时候方便,当你碰到问题想清理的时候可就蛋疼了,相信
维护服务器的SA也不太可能会让你这样做的。
virtualenv+源码直接安装
比较靠谱的办法,但是只适合单机部署。当服务器数量众多,如何实现批量部署发布就是
个困难的问题了。
virtualenv+源码打包发布
在virtualenv环境里安装好所有的Python文件,把整个virtualenv目录打包成一个单独的
tar包。发布时直接将这个tar包拷贝到目标服务器上解压安装。
目前一些知名的Openstack厂商,如Rackspace,就是通过这种方式在服务器上部署Python
项目的。
然而,这样做的缺点是,还需要做很多额外的工作去维护服务的配置文件、脚本、系统上
非Python相关的软件依赖(如kvm、libvirt、openvswitch)等等。
类似方法还有自建私有PyPI源,提前将Python项目打包上传到自建的PyPI源里。然后在
服务器上的virtualenv环境里通过自建的PyPI源安装。
使用Linux发行版本身的安装包
比如,Debian系的.deb安装包、Redhat系的.rpm安装包。它们能比较好的维护各种服务
配置文件、脚本,以及像kvm这样的非Python相关的依赖,我们目前也在使用这种方式。
然而,它也有很多问题,以我比较熟悉的Debian发行版为例:
所有Python项目共用一套Python依赖。当有的Python项目想升级某个第三方库时,会
因为破坏其他Python项目的依赖版本而无法实现。官方提供的软件版本比较旧。对于一个追求稳定的Linux发行版,这么做本身并无可厚
非,但是有时候当你就是想用新一点版本时,就会感觉非常无奈,基本都要自己动手制
作安装包。而且由于依赖的关系,可能你为了给一个软件制作新版本的安装包,需要再
为其他10个依赖的项目制作新版本的安装包,然后又要为这10个依赖的项目再制作30个
依赖的依赖的新版本安装包。。。学习成本比较高。Debian的安装包制作方法,除了官方十年前写的几份文档外,网上
其他能找到的资料很少,学起来比较费力。Debian作为一个装机量较大的Linux发行版都
是这样,相信其他发行版也是类似的情况。
virtualenv+源码+Linux发行版安装包打包发布
在virtualenv环境里安装好所有的Python文件,然后将整个virtualenv目录打包到单独的
一个Linux发行版的安装包内,同时在这个安装包内设置好相关的配置文件、脚本、系统
依赖。
理论上这种方法综合了上面两种方式的优点,目前正在调研中,然而相信实践过程中肯定
会踩到不少坑。
spotify公布了他们在Debian下使用这种方式解决Python项目发布问题的工具dh-virtualenv8 ,感兴趣的同学可以参考一下。
References
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 知物由学|虚假色情泛滥,人工智能可以做些啥?
【推荐】 关于数据库查询业务的几点思考
Python包管理工具小结的更多相关文章
- python 包管理工具
python 包管理工具 Python当前的包管理工具链是 easy_install/pip + distribute/setuptools + distutils,显得较为混乱. 而将来的工具链组合 ...
- Python 包管理工具解惑
Python 包管理工具解惑 本文链接:http://zengrong.net/post/2169.htm python packaging 一.困惑 作为一个 Python 初学者,我在包管理上感到 ...
- Python包管理工具和多版本环境管理
1. Python包管理工具 在安装Python包的过程中,经常涉及到distutils.setuptools.distribute.setup.py.easy_install.easy_instal ...
- 转载:Python 包管理工具解惑
Python 包管理工具解惑 本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商: 本站部分原创和翻译文章提供m ...
- Python包管理工具pip的基本使用
1.简介 pip 是一个Python包管理工具,主要是用于安装 PyPI 上的软件包,可以替代 easy_install 工具. 2.pip安装 如果你安装的Python 2 >=2.7.9 或 ...
- python包管理工具他们之间的关系
python包管理工具之间的关系 现在的python包管理工具有很多,非常混乱,必须理清他们之间的关系才能更好的使用python构建强大的包关系系统工具. 首先:python官方推荐的第三方库是PyP ...
- Python | Pipenv官方推荐的python包管理工具
原文地址:https://cloud.tencent.com/developer/article/1355672 Pipenv - 官方推荐的的python包管理工具. Pipenv是一款旨在将所有包 ...
- [转载]Python 包管理工具
[转载]Python 包管理工具 最近由于机缘巧合,使用各种方法安装了一些Python包,所以对Python的包管理开始感兴趣.在网上找到一篇很好的文章:https://blog.zengrong.n ...
- python 包管理工具 pip 的配置
近几年来,python的包管理系统pip 越来越完善, 尤其是对于 windows场景下,pip大大改善了python的易用性. https://www.cnblogs.com/yvivid/p/pi ...
随机推荐
- Spanner: Google’s Globally-Distributed Database
https://research.google.com/archive/spanner.html Spanner is Google’s scalable, multi-version, global ...
- BCH分叉是一次站队博弈
BCH分叉在即,很多人说BCH本次分叉实质是大佬间的斗争,主要是本次BCH分叉主要分为两大派别: 一派以BCH用户量最大的客户端Bitcoin ABC开发组为主,要在11月15日展开硬分叉升级,主要升 ...
- .idea文件夹是干嘛的
question python为什么每次创建的文件目录下都含有.idea/文件夹,该文件夹又是用来干嘛的 answer 当使用pycharm作为IDE时,会自动生成.idea/文件夹来存放项目的配置信 ...
- PAT 甲级 1116. Come on! Let's C (20) 【循环判断】
题目链接 https://www.patest.cn/contests/pat-a-practise/1116 思路 注意一个细节 如果没有本来 ID 的 后来又查了这个ID 不是输出 checked ...
- Centos虚拟机克隆后的ip配置
1. rm -rf /etc/udev/rules.d/-persistent-net.rules 2. 重启,然后: vi /etc/udev/rules.d/70-persistent-net.r ...
- PYTHON 爬虫笔记十:利用selenium+PyQuery实现淘宝美食数据搜集并保存至MongeDB(实战项目三)
利用selenium+PyQuery实现淘宝美食数据搜集并保存至MongeDB 目标站点分析 淘宝页面信息很复杂的,含有各种请求参数和加密参数,如果直接请求或者分析Ajax请求的话会很繁琐.所以我们可 ...
- kvm初体验之二:安装
Host: CentOS release 6.4 (Final) 1. 开启处理器的虚拟化功能 进入BIOS,使能虚拟化功能: 进入linux, grep -E "vmx|svm" ...
- 基类的两个派生类再派生一个派生类 用virtual避免二义性
class vehicle{ int MaxSpeed; int Weight;public: vehicle(int maxspeed, int weight) :MaxSpeed(maxspeed ...
- 机器视觉 之 Gabor Feature
在机器视觉中,gabor feature是一种比较常见的特征,因为其可以很好地模拟人类的视觉冲击响应而被广泛应用于图像处理, gabor feature 一般是通过对图像与gabor filter做卷 ...
- WEB攻击之 CSRF 攻击及防御策略
介绍 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法. 释义: 跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如 ...