使用setuptools打包
当我们写一个完整的项目,需要该项目文件中打包成分发包共享给他人或者上传到pypi社区以供他人下载。这就需要对该项目进行打包分发。
项目文件
这是一个已写好的项目文件包,叫做my_pkg
,它的目录结构如下:
tutorial/
my_pkg/
__init__.py
main.py
utils/
__init__.py
other.py
在my_pkg中有两个文件和一个子包utils
,现在我们需要对这个my_pkg进行打包。
创建包文件和setup.py文件
my_pkg是将打包的Python包文件,在my_pkg的同级目录下分别创建以下文件:
- setup.py ---- 打包脚本文件,执行该脚本将自动完成打包
- LICENCE ---- 许可证文件
- README ---- 包的介绍和说明
创建后文件目录结构如下:
tutorial/
my_pkg/
__init__.py
main.py
utils/
__init__.py
other.py
setup.py
LICENCE
README
setup.py配置
打开setup.py文件,写入以下内容
import setuptools # 导入setuptools, 基于setuptools模块进行打包分发
# 将readme文件中内容加载进来,作为对包的详细说明(可以不需要)
with open("README.md", "r") as fh:
long_description = fh.read()
# 调用setuptools的setup进行打包,通过参数配置指定包的信息,这是打包的关键设置
setuptools.setup(
name="my_pkg", # 这是该包的名字,将来可能使用pip install 该包名直接下载
version="0.0.1", #版本号,
author="Example Author", #作者
author_email="author@example.com", # 作者邮箱
description="A small example package", # 包简短的描述
long_description=long_description, # 详细的描述,这里使用从readme中读取的内容
long_description_content_type="text/markdown", # 详细描述来源文件的文件类型,这里使用markdomn
url="https://github.com/pypa/my_pkg", # 可以将项目上传到github,gitlab等,在此指定链接地址以供下载。
# 指定需要打包的内容,输入需要打包包名字符串列表,打包时不会自动获取子包,需要手动指定,例如:["my_pkg", "mypkg.utils"]
packages=setuptools.find_packages(), # 使用该函数可以自动打包该同级目录下所有包
classifiers=[ # 指定一些包的元数据信息,例如使用的协议,操作系统要求
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6', # 该包的Python版本要求
)
setup.py中除了上述内容,还可以添加包括以下的信息
name package name
version (-V) package version
fullname <package name>-<version>
author the author's name
author-email the author's email address
maintainer the maintainer's name
maintainer-email the maintainer's email address
contact the maintainer's name if known, else the author's
contact-email the maintainer's email address if known
url the URL for this package
license the license of the package
licence for --license
description the package description
long-description the long package description
platforms the list of platforms
classifiers the list of classifiers
keywords the list of keywords
provides the list of packages/modules provided
requires the list of packages/modules required
obsoletes the list of packages/modules made obsolete
setup.py配置完成后,就可以执行这个文件进行打包了(在命令行使用Python解释器指定参数执行,不能直接执行),在此之前还有LICENCE
和README
两个文件需要完善(也可以不做处理,不影响打包执行)。
README
这个文件是该包的详细说明文件,包括各种信息,例如该包如何安装,需要的环境,如何使用等详细内容。
LICENCE
指定许可证信息,开源软件都遵循了不同的开源协议,这些协议规定了使用者使用该包后必须遵守的原则,可以查看不同开源协议内容 https://choosealicense.com/ ,选则一个协议,复制对应的协议内容到该文件中即可:
示例选择MIT协议
Copyright (c) 2018 The Python Packaging Authority
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
通过setup.py生成分发包
setup.py文件配置完成后,就可以通过Python执行进行打包,使用cmd命令行工具打开终端,cd 到setup.py文件所在目录(windows 可以在文件资源管理器中的setup.py目录上方路径中直接cmd,直接在该目录打开终端)
打包成wheel二进制包
这需要最新的setuptools 和 wheel包。执行以下命令更新
python -m pip install --user --upgrade setuptools wheel
执行该setup.py文件并指定参数,指定打包为wheel二进制文件。
python setup.py sdist bdist_wheel
执行该命令后,该目录下会多出三个目录。在dist目录下就是我们打包好的源代码文件(tar.gz)和wheel二进制文件(.whl)。
build
dist/
my_pkg-0.0.1.tar.gz # 被打包内容所有原代码,按照原有的层级结构
my_pkg-0.0.1-py3-none-any-whl # 可以通过pip install 直接安装
my_pkg.egg-info
现在我们可以及将这个dist文件夹中的内容共享给他人,也可以上传pypi社区供他人下载安装,在得到这个dist包后,可以通过pip安装命令直接安装内部的.whl
文件。
pip install my_pkg-0.0.1-py3-none-any-whl
该命令会将这个包安装到python安装目录下/Lib/site-packages目录下,使用pip list
命令可以看到在列表中出现了名为my_pkg
的包名,安装成功。该包可以使用了。
如果将该包上传到pypi社区供他人下载,需要注意自己包名不要和其他贡献者的包名相同,如何判断是否重复,尝试在未上传前使用pip isntall 包名
进行安装,若没有找到找到该package表示该名可用,也可以上pypi官网搜索。上传成功后,直接使用pip install 包名
进行安装。上传pypi过程见官网示例https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives
打包为源码包-sdist
通过wheel二进制文件打包是目前较为流行的方式。除了wheel二进制文件,我们还可以使用Python源代码压缩文件形式进行打包。同样在setup.py同级目录下,进入cmd命令行,执行命令
python setup.py sdist
将会在创建dist和my_pkg.egg.info目录。我们只关心dist目录,该目录下有一个压缩文件,这个压缩文件包含了打包后的全部源码。
dist/
my_pkg-0.0.1.tar.gz
将该文件发送给他人,可以直接使用pip install my_pkg-0.0.1.tar.gz
直接安装该包,同样在使用pip list
可以查看到该包名。
另外,还可以解压该源码包,在setup.py
目录执行python setup.py install
安装该包。
二进制安装程序-bdist
打包为二进制安装包,生成目标操作系统的安装程序。
生成windows 安装程序
针对windows环境下,以下三条命令均可
python setup.py bdist_wininst
Python setup.py bdist_msi
python setup.py bdist --format=msi
创建一个dist目录,生成一个安装程序,在Windows上直接双击即可安装该包。
生成rpm包
python setup.py bdist_rpm
python setup.py bdist -- format=rpm
在Linux系统中使用rpm命令进行安装。
生成压缩文件
python setup.py bdist --format=zip
python setup.py bdist --format=gztar