详解Python打包分发工具setuptools


Posted in Python onAugust 05, 2019

Python打包分发工具setuptools:曾经 Python 的分发工具是 distutils,但它无法定义包之间的依赖关系。setuptools 则是它的增强版,能帮助我们更好的创建和分发 Python 包,尤其是具有复杂依赖关系的包。其通过添加一个基本的依赖系统以及许多相关功能,弥补了该缺陷。他还提供了自动包查询程序,用来自动获取包之间的依赖关系,并完成这些包的安装,大大降低了安装各种包的难度,使之更加方便,将程序打包以后可以可以安装到自己的虚拟环境中,也可以上传到PyPI,这样非常方便大项目开发

setuptools使用

pip 安装:

$ pip install setuptools

第一个安装文件 在目录 learn_setup 下新建安装文件 setup.py,然后创建包 myapp 模拟要打包源码包:

├── myapp
│ └── __init__.py
└── setup.py

setup.py 文件内容如下:

from setuptools import setup
setup(
 name='firstApp001', # 应用名
 version='0.0.1', # 版本号
 packages=['myapp'], # 包括在安装包内的 Python 包
)

使用安装文件创建 wheel 有了上面的 setup.py 文件,我们就可以打出各种安装包,主要分为两类:sdist 和 bdist。 Source distribution 使用 sdist 可以打包成 source distribution,支持的压缩格式有:

详解Python打包分发工具setuptools

使用方式为:

$ python setup.py sdist --formats=gztar,zip

目录下便会多出 dist 和 *.egg-info 目录,dist 内保存了我们打好的包,上面命令使用 --formats 指定了打出 .tar.gz 和 .zip 包,如果不指定则如上表根据具体平台默认格式打包。 包的名称为 setup.py 中定义的 name, version以及指定的包格式,格式如:firstApp01-0.0.1.tar.gz。

Built distribution 使用 bdist 可以打出 built distribution,和源码包相比,由于预先构建好,所以安装更快:

详解Python打包分发工具setuptools

使用上,和 sdist 一样,可以使用 --formats 指定包格式。如:

$ python setup.py bdist --formats=rpm

同时为了简化操作,setuptools 提供了如下命令:

详解Python打包分发工具setuptools

所以上面打 rpm 包可以使用:

$ python setup.py bdist_rpm

Wheel Wheel 也是一种 built 包,而且是官方推荐的打包方式。也许你曾经遇见或使用过 egg 包,但现在wheel 是官方推荐的打包方式 使用 wheel 打包,首先要安装 wheel:

$ pip install wheel

然后使用 bdist_wheel 打包:

$ python setup.py bdist_wheel

执行成功后,目录下除了 dist 和 *.egg-info 目录外,还有一个 build 目录用于存储打包中间数据。 wheel 包的名称如 firstApp01-0.0.1-py3-none-any.whl,其中 py3 指明只支持 Python3。可以使用参数 --universal,包名如 mfirstApp-0.0.1-py2.py3-none-any.whl,表明 wheel 包同时支持 Python2 和 Python3使用 universal 也成为通用 wheel 包,反之称为纯 wheel 包。

安装 Wheel 上一节的示例应用没有任何内容。下面添加模块 greet 并重新打包。

# one.py
def hello():
 print('Hello, welcome to setuptools!')

使用 bdist_wheel 再次打包后,我们可以使用 pip 安装到本地 Python 的 site-packages 目录。

$ pip install dist/fisrtApp001-0.0.1-py3-none-any.whl

现在和其他使用 pip 安装的三方库一样使用:

from one.greet import hello
hello()

应用开发过程中会频繁变更,每次安装都需要先卸载旧版本很麻烦。使用 develop 开发模式安装的话,实际代码不会拷贝到 site-packages 下,而是除一个指向当前应用的链接(*.egg-link)。这样当前位置的源码改动就会马上反映到 site-packages。使用如下

$ pip install -e .  # 或者 python setup.py develop

要是需要卸载,就使用pip uninstall 上传 Wheel 到 PyPI Wheel 包可以自己使用和传输给其他人使用,但是维护更新不方便,而 PyPI 作为 Python 的 软件仓库,让所有人可以方便的上传和下载,以及管理三方库。

注册 PyPI 账号 登录 pypi.python.org/pypi,进入 Register 注册账号。

安装 twine虽然 setuptools 支持使用 setup.py upload 上传包文件到 PyPI,但只支持 HTTP 而被新的 twine 取代,同样的,需要先安装 twine:

$ pip install twine

使用 twine 上传 使用 upload:

$ twine upload dist/*

输入 username 和 password 即上传至 PyPI。如果不想每次输入账号密码,可以在家目录下创建 .pypirc 文件,内容如下:

[distutils]
index-servers =
 pypi
 pypitest

[pypi]
username: 
password:

[pypitest]
repository: https://test.pypi.org/legacy/
username: 
password:

填上自己的账号密码即可,这里配置了官方的 pypi 和 pypitest,若要配置其他仓库,按格式添加。回到 PyPI 主页即可看到上传的 firstApp001

详解Python打包分发工具setuptools

setup() 参数

详解Python打包分发工具setuptools
详解Python打包分发工具setuptools

上面的 setup.py 安装文件内,我们已经使用了 setup() 一些参数:name, version, packages。 version 项目版本号,一般由三部分组成:MAJOR, MINOR, MAINTENANCE。

  • MAJOR version when they make incompatible API changes,
  • MINOR version when they add functionality in a backwards-compatible manner, and
  • MAINTENANCE version when they make backwards-compatible bug fixes. 版本号的选择参见: packaging.python.org/tutorials/d… packages:列出项目内需要被打包的所有 package。一般使用 setuptools.find_packages() 自动发现。
  • packages=find_packages(exclude=['contrib', 'docs', 'tests*'])
  • # exclude 用于排除不打包的 package

description:项目的简短描述,一般一句话就好,会显示在 PyPI 上名字下端。

description='My first Python project'

对项目的完整描述,使用 long_description。如果此字符串是 rst 格式的,PyPI 会自动渲染成 HTML 显示。也可指定使用 markdown。

long_description=long_description,
long_description_content_type='text/x-rst'

url:通常为 GitHub上 的链接或者 readthedocs 的链接。

url='https://github.com/pypa/sampleproject'

author:作者信息

author='example',
author_email='example@example.com'

license:项目许可证

license='MIT'

关于各种许可证的介绍和选择,参考:choosealicense.com/ classifiers:项目分类,完整可选项参考: pypi.python.org/pypi?%3Aact…

classifiers=[
 # How mature is this project? Common values are
 # 3 - Alpha
 # 4 - Beta
 # 5 - Production/Stable
 'Development Status :: 3 - Alpha',

 # Indicate who your project is intended for
 'Intended Audience :: Developers',
 'Topic :: Software Development :: Build Tools',

 # Pick your license as you wish (should match "license" above)
  'License :: OSI Approved :: MIT License',

 # Specify the Python versions you support here. In particular, ensure
 # that you indicate whether you support Python 2, Python 3 or both.
 'Programming Language :: Python :: 2',
 'Programming Language :: Python :: 2.6',
 'Programming Language :: Python :: 2.7',
 'Programming Language :: Python :: 3',
 'Programming Language :: Python :: 3.2',
 'Programming Language :: Python :: 3.3',
 'Programming Language :: Python :: 3.4',
],

keywords:项目关键词列表

keywords='sample setuptools development'

project_urls:项目相关额外连接,如代码仓库,文档地址等。

project_urls={
 'Documentation': 'https://packaging.python.org/tutorials/distributing-packages/',
 'Funding': 'https://donate.pypi.org',
 'Say Thanks!': 'http://saythanks.io/to/example',
 'Source': 'https://github.com/pypa/sampleproject/',
 'Tracker': 'https://github.com/pypa/sampleproject/issues',
}

install_requires:项目依赖的 Python 库,使用 pip 安装本项目时会自动检查和安装依赖。

install_requires=['pyyaml']

依赖的安装参考: packaging.python.org/discussions… python_requires:指定项目依赖的 Python 版本

python_requires='>=3'

package_data:项目依赖数据文件,数据文件必须放在项目目录内且使用相对路径

package_data={
 'myapp': ['data/*.yml'],
}

如果不指定作为目录的键为空串,则代表对所有模块操作(下例中将包含所有包内 data 目录下的 yaml 文件):

package_data={
 '': ['data/*.yml'],
}

data_files:如果数据文件存在于项目外,则可以使用 data_files 参数或者 MANIFEST.in 文件进行管理。如果用于源码包,则使用 MANIFEST.in;如果用于 wheel,则使用 data_files。

data_files=[(‘mydata', [‘data/conf.yml'])]

上述设置将在打包 wheel 时,将 data/conf.yml 文件添加至 mydata 目录。(data_files 不能使用路径通配符) 此外,scripts, py_modeles, entry_points, console_scripts 等参数参考: packaging.python.org/tutorials/d… 其他初始化文件 在阅读 Github 上的 Python 库时,除了最基本核心的 setup.py 文件和主程序之外,还会看到其他一些文件。本节将介绍它们的作用和使用方法。

setup.cfg 包含了构建时候的一些默认参数,如:

[bdist_wheel]
universal=1

用于在使用 bdist_wheel 的时候的默认设置 --universal 参数 。

README.rst/README.md:项目说明文档,使用 reStrutruedText 可以在 PyPI 上很好的渲染,但 Markdown 则支持不够好。

MANIFEST.in:此文件在打源码包的时候告诉 setuptools 还需要额外打包哪些文件。

# Include the README
include *.md
# Include the license file
include LICENSE.txt
# Include the data files
recursive-include data *

LICENSE.txt:项目许可说明文件 setuptools 默认打包的文件:README.rst/README.md、setup.cfg、MANIFEST.in 所以其他的文件,如 LICENSE.txt,在源码包时需要手动在 MANIFEST.in 里添加 include,在 wheel 包时需要在 setup.cfg 添加:

[metadata]
license_file = LICENSE.txt

PyPI 上传推荐配置

setup.py 
name
version
author
author_email
url
packages
description
package_data/data_files
setup.cfg
MANIFEST.in
README.rst
LICENSE.txt
<项目>

官网例子参考:

from setuptools import setup, find_packages
setup(
 name="HelloWorld",
 version="0.1",
 packages=find_packages(),
 scripts=['say_hello.py'],

 # Project uses reStructuredText, so ensure that the docutils get
 # installed or upgraded on the target machine
 install_requires=['docutils>=0.3'],

 package_data={
  # If any package contains *.txt or *.rst files, include them:
  '': ['*.txt', '*.rst'],
  # And include any *.msg files found in the 'hello' package, too:
  'hello': ['*.msg'],
 },

 # metadata to display on PyPI
 author="Me",
 author_email="me@example.com",
 description="This is an Example Package",
 keywords="hello world example examples",
 url="http://example.com/HelloWorld/", # project home page, if any
 project_urls={
  "Bug Tracker": "https://bugs.example.com/HelloWorld/",
  "Documentation": "https://docs.example.com/HelloWorld/",
  "Source Code": "https://code.example.com/HelloWorld/",
 },
 classifiers=[
  'License :: OSI Approved :: Python Software Foundation License'
 ]

 # could also include long_description, download_url, etc.
)

参考: setuptools.readthedocs.io/en/latest/s…

总结

以上所述是小编给大家介绍的Python打包分发工具setuptools,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python多线程threading.Lock锁用法实例
Nov 01 Python
Python文件读取的3种方法及路径转义
Jun 21 Python
Python连接phoenix的方法示例
Sep 29 Python
python处理数据,存进hive表的方法
Jul 04 Python
Django基础知识与基本应用入门教程
Jul 20 Python
python 多线程中子线程和主线程相互通信方法
Nov 09 Python
python tools实现视频的每一帧提取并保存
Mar 20 Python
python3+PyQt5 自定义窗口部件--使用窗口部件样式表的方法
Jun 26 Python
python获取array中指定元素的示例
Nov 26 Python
使用Python实现Wake On Lan远程开机功能
Jan 22 Python
完美解决ARIMA模型中plot_acf画不出图的问题
Jun 04 Python
python中 _、__、__xx__()区别及使用场景
Jun 30 Python
Django 1.10以上版本 url 配置注意事项详解
Aug 05 #Python
TensorFlow车牌识别完整版代码(含车牌数据集)
Aug 05 #Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
Aug 05 #Python
Django应用程序入口WSGIHandler源码解析
Aug 05 #Python
详解如何用TensorFlow训练和识别/分类自定义图片
Aug 05 #Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
Aug 05 #Python
Python获取时间范围内日期列表和周列表的函数
Aug 05 #Python
You might like
php 缩略图实现函数代码
2011/06/23 PHP
php提示undefined index的几种解决方法
2012/05/21 PHP
PHP中使用Memache作为进程锁的操作类分享
2015/03/30 PHP
PHP中的命名空间详细介绍
2015/07/02 PHP
php htmlentities()函数的定义和用法
2016/05/13 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
PHP使用pdo连接access数据库并循环显示数据操作示例
2018/06/05 PHP
PHP进阶学习之依赖注入与Ioc容器详解
2019/06/19 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
CL vs ForZe BO5 第一场 2.13
2021/03/10 DOTA
[全兼容哦]--实用、简洁、炫酷的页面转入效果loing
2007/05/07 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
2011/12/29 Javascript
jQuery lazyLoad图片延迟加载插件的优化改造方法分享
2013/08/13 Javascript
javascript跨域的4种方法和原理详解
2014/04/08 Javascript
JavaScript中三种异步上传文件方式
2016/03/06 Javascript
BootStrap点击下拉菜单项后显示一个新的输入框实现代码
2016/05/16 Javascript
BootStrap 模态框实现刷新网页并关闭功能
2017/01/04 Javascript
javascript 网页进度条简单实例
2017/02/22 Javascript
vuex 项目结构目录及一些简单配置介绍
2018/04/08 Javascript
使用webpack/gulp构建TypeScript项目的方法示例
2019/12/18 Javascript
vue学习之Vue-Router用法实例分析
2020/01/06 Javascript
[02:17]DOTA2亚洲邀请赛 RAVE战队出场宣传片
2015/02/07 DOTA
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
详解python statistics模块及函数用法
2019/10/27 Python
使用python实现数组、链表、队列、栈的方法
2019/12/20 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
2019/12/26 Python
python列表返回重复数据的下标
2020/02/10 Python
html5绘制时钟动画
2014/12/15 HTML / CSS
Expedia挪威官网:酒店、机票和租车
2018/03/03 全球购物
护理专业应届毕业生推荐信
2013/11/15 职场文书
村级个人对照检查材料
2014/08/22 职场文书
婚礼伴郎致辞
2015/07/28 职场文书
安全生产感想
2015/08/07 职场文书
nginx 防盗链防爬虫配置详解
2021/03/31 Servers
《黑岩★★射手 DAWN FALL》BD发售宣传CM公开
2022/04/04 日漫