1、项目打包工具:
- distutils 是 Python 的一个标准库
- setuptools 是 distutils 增强版,不包括在标准库中
- distribute 是 setuptools 一个分支版本
- distutils2 废弃
2、安装 setuptools
文档: https://setuptools.readthedocs.io/
- 方式一:源码安装
https://pypi.org/project/setuptools/#files下载 zip 包解压
$ python setup.py install
- 方式二:通过引导程序安装
$ wget http://peak.telecommunity.com/dist/ez_setup.py
# 安装
$ python ez_setup.py
# 更新,以下两种任选
$ python ez_setup.py –U setuptools
$ pip install -U setuptools
- 方式三: pip安装
$ pip install --upgrade setuptools
3、使用 easy_install
安装完 setuptools 后,就有了easy_install 的第三方管理工具
- 包的安装
# 通过包名,从PyPI寻找最新版本,自动下载、编译、安装
$ easy_install pkg_name
# 通过包名从指定下载页寻找链接来安装或升级包
$ easy_install -f http://pythonpaste.org/package_index.html
# 指定线上的包地址安装
$ easy_install http://example.com/path/to/MyPackage-1.2.3.tgz
# 从本地的 .egg 文件安装
$ easy_install xxx.egg
# 在安装时你可以添加额外的参数
指定安装目录:--install-dir=DIR, -d DIR
指定用户安装:--user
- 包的升级
# 从 pypi 中搜索并升级包
$ easy_install --upgrade pkg_name
# 指定版本进行升级
$ easy_install "SomePackage==2.0"
- 包的删除
$ easy_install -m pkg_name
若要删除彻底,需要手动删除相关的 .egg 及 其他文件
指定安装源
~/.pydistutils.cfg
[easy_install]
index-url=http://mirrors.aliyun.com/pypi/simple/
find-links=http://mirrors.aliyun.com/pypi/simple/
4、源码包与二进制包
- 源码包
常见后缀:.zip, .tar, .tar.gz, .tar.bz2, .tar.Z
安装的过程,是先解压,再编译,最后才安装。安装速度较慢, 跨平台
- 二进制包
常见后缀:.egg, .whl
安装过程:省去了编译的过程,直接进行解压安装。安装速度较快。
5、setup.py 的编写
简单的使用示例
from setuptools import setup, find_packages
setup(
name="mytest",
version="1.0",
author="wangbm",
author_email="wongbingming@163.com",
description="Learn to Pack Python Module",
# 项目主页
url="http://www.baidu.com/",
# 你要安装的包,通过 setuptools.find_packages 找到当前目录下有哪些包
packages=find_packages()
)
6、setup 参数
setup 函数常用的参数如下
参数 | 说明 |
---|---|
name | 包名称 |
version | 包版本 |
author | 程序的作者 |
author_email | 程序的作者的邮箱地址 |
maintainer | 维护者 |
maintainer_email | 维护者的邮箱地址 |
url | 程序的官网地址 |
license | 程序的授权信息 |
description | 程序的简单描述 |
long_description | 程序的详细描述 |
platforms | 程序适用的软件平台列表 |
classifiers | 程序的所属分类列表 |
keywords | 程序的关键字列表 |
packages | 需要处理的包目录(通常为包含 init.py 的文件夹) |
py_modules | 需要打包的 Python 单文件列表 |
download_url | 程序的下载地址 |
cmdclass | 添加自定义命令 |
package_data | 指定包内需要包含的数据文件 |
include_package_data | 自动包含包内所有受版本控制(cvs/svn/git)的数据文件 |
exclude_package_data | 当 include_package_data 为 True 时该选项用于排除部分文件 |
data_files | 打包时需要打包的数据文件,如图片,配置文件等 |
ext_modules | 指定扩展模块 |
scripts | 指定可执行脚本,安装时脚本会被安装到系统 PATH 路径下 |
package_dir | 指定哪些目录下的文件被映射到哪个源码包 |
entry_points | 动态发现服务和插件,下面详细讲 |
python_requires | 指定运行时需要的Python版本 |
requires | 指定依赖的其他包 |
provides | 指定可以为哪些模块提供依赖 |
install_requires | 安装时需要安装的依赖包 |
extras_require | 当前包的高级/额外特性需要依赖的分发包 |
tests_require | 在测试时需要使用的依赖包 |
setup_requires | 指定运行 setup.py 文件本身所依赖的包 |
dependency_links | 指定依赖包的下载地址 |
setup.cfg 文件提供 setup.py 的默认参数
配置:https://docs.python.org/3/distutils/configfile.html
- classifiers 分类信息
参见:https://pypi.org/pypi?%3Aaction=list_classifiers
示例:
from setuptools import setup, find_packages
setup(
classifiers = [
# 发展时期,常见的如下
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',
# 开发的目标用户
'Intended Audience :: Developers',
# 属于什么类型
'Topic :: Software Development :: Build Tools',
# 许可证信息
'License :: OSI Approved :: MIT License',
# 目标 Python 版本
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
]
)
- 文件的分发
from setuptools import setup, find_packages
setup(
name="mytest",
version="1.0",
author="wangbm",
author_email="wongbingming@163.com",
description="Learn to Pack Python Module",
url="http://iswbm.com/",
packages=find_packages(),
# 安装过程中,需要安装的静态文件,如配置文件、service文件、图片等
data_files=[
('', ['conf/*.conf']),
('/usr/lib/systemd/system/', ['bin/*.service']),
],
# 希望被打包的文件
package_data={
'':['*.txt'],
'bandwidth_reporter':['*.txt']
},
# 不打包某些文件
exclude_package_data={
'bandwidth_reporter':['*.txt']
}
)
还可以使用 MANIFEST.in
include *.txt
recursive-include examples *.txt *.py
prune examples/sample?/build
配置:https://docs.python.org/3.6/distutils/sourcedist.html
- 依赖包下载安装
from setuptools import setup, find_packages
setup(
...
# 表明当前模块依赖哪些包,若环境中没有,则会从pypi中下载安装
install_requires=['docutils>=0.3'],
# setup.py 本身要依赖的包,这通常是为一些setuptools的插件准备的配置
# 这里列出的包,不会自动安装。
setup_requires=['pbr'],
# 仅在测试时需要使用的依赖,在正常发布的代码中是没有用的。
# 在执行python setup.py test时,可以自动安装这三个库,确保测试的正常运行。
tests_require=[
'pytest>=3.3.1',
'pytest-cov>=2.5.1',
],
# 用于安装setup_requires或tests_require里的软件包
# 这些信息会写入egg的 metadata 信息中
dependency_links=[
"http://example2.com/p/foobar-1.0.tar.gz",
],
# install_requires 在安装模块时会自动安装依赖包
# 而 extras_require 不会,这里仅表示该模块会依赖这些包
# 但是这些包通常不会使用到,只有当你深度使用模块时,才会用到,这里需要你手动安装
extras_require={
'PDF': ["ReportLab>=1.2", "RXP"],
'reST': ["docutils>=0.3"],
}
)
- 安装环境的限制
setup(
...
python_requires='>=2.7, <=3',
)
- 生成可执行文件
from setuptools import setup, find_packages
setup(
name="mytest",
version="1.0",
author="wangbm",
author_email="wongbingming@163.com",
description="Learn to Pack Python Module",
url="http://iswbm.com/",
packages=find_packages(),
# 用来支持自动生成脚本,安装后会自动生成 /usr/bin/foo 的可执行文件
# 该文件入口指向 foo/main.py 的main 函数
entry_points={
'console_scripts': [
'foo = foo.main:main'
]
},
# 将 bin/foo.sh 和 bar.py 脚本,生成到系统 PATH中
# 执行 python setup.py install 后
# 会生成 如 /usr/bin/foo.sh 和 如 /usr/bin/bar.py
scripts=['bin/foo.sh', 'bar.py']
)
7、 使用 setup.py 构建包
- 构建源码发布包
$ python setup.py sdist
# 指定发布包格式
$ python setup.py sdist --formats=gztar,zip
# 安装
$ easy_install xxx.tar.gz
参数:
格式 | 后缀 |
---|---|
zip | .zip |
gztar | .tar.gz |
bztar | .tar.bz2 |
xztar | .tar.xz |
ztar | .tar.Z |
tar | .tarzip_safe |
文档: https://docs.python.org/3.6/distutils/sourcedist.html
- 构建二进制分发包
# exe 包
$ python setup.py bdist_wininst
# rpm 包
$ python setup.py bdist_rpm
# egg 包
$ python setup.py bdist_egg
# 生成多个格式的进制包
$ python setup.py bdist
8、使用 setup.py 安装包
# 将模块安装至系统全局环境
$ python setup.py install
# 在系统环境中创建一个软链接指向包实际所在目录
$ python setup.py develop
# 卸载
$ python setup.py develop --uninstall
$ python setup.py develop -u
9、发布包到 PyPi
~/.pypirc 配置 PyPI 访问地址和账号
[distutils]
index-servers = pypi
[pypi]
username:xxx
password:xxx
# 信息注册
$ python setup.py register
# 上传源码包
$ python setup.py upload
也可以使用 twine 工具注册上传
python setup.py sdist bdist_wheel && twine upload dist/*
参考文章