Python 高手编程系列三千四百四十二:创建一个包

Python 高手编程系列三千四百四十二:创建一个包 Python打包一开始可能有些难以理解。其主要原因是不了解创建Python包的正确工具。不管怎样一旦创建了第一个包你就会发现它并不像看起来那么难。此外熟悉正确且最先进的打包工具也很有帮助。你即使对将代码开源分发不感兴趣但也应该知道如何创建包。知道如何创建自己的包可以让你深入了解打包生态系统并且有助于你使用 PyPI 上可用的第三方代码。此外将你的闭源项目或其组件变成源代码发行包有助于你在不同的环境中部署代码。下一章将会更详细地描述在代码部署过程中使用 Python 打包生态系统的优点。本章我们将重点介绍创建这些发行版的正确工具和技术。Python 打包工具的混乱状态Python 打包曾经在很长一段时间内处于混乱不堪的状态人们花了很多年才使得这一主题重新变得有组织。一切都从 1998 年引入的 distutils 包开始随后在 2003 年setuptools 对其进行改进。这两个项目开启了一段漫长而又纠结的故事故事包括派生fork、替代项目与完全重新编写都想要彻底修复 Python 的打包生态系统。不幸的是大部分尝试都没有成功。效果恰恰相反。每个想要取代 setuptools 或 distutils 的新项目只是给打包工具十分混乱的状态添乱而已。有些派生被合并回它们的祖先中例如setuptools 派生的 distribute但有些则被弃用distutils2。幸运的是这种状态正在逐步改变。成立了一个叫作 Python Packaging Authority(PyPA)的组织将秩序和组织性带回到打包生态系统中。PyPA 维护的 Python 打包用户指南Python Packaging User Guidehttps://packaging.python.org是关于最新打包工具和最佳实践的权威信息来源。你可以将它当作关于打包的最佳信息来源也可以当作本章的补充阅读。这份指南还包含详细的历史变化以及与打包相关的新项目因此如果你已经了解一些内容、但想要确保使用的是正确的工具那么这份指南是很有用的。要远离其他流行的互联网资源例如 The Hitchhiker’s Guide to Packaging。它的内容陈旧、没人维护而且大部分都是过时的。对它的兴趣只可能是历史原因事实上Python打包用户指南就是这份旧资源的派生。由于 PyPA 的存在Python 打包的现状PyPA 除了提供一份权威的打包指南之外还维护着打包项目与新的官方打包的标准化过程。请参阅https://github.com/pypa。本书已经提到过其中一些项目。其中最有名的是• pip• virtualenv• twine• warehouse。注意大部分项目都是在这个组织之外开始的只是作为一个成熟且广泛使用的解决方案迁移到 PyPA 的赞助下。由于 PyPA 的参与构建发行版已经正在逐步弃用 egg 格式而是支持使用 wheel 格式。未来可能会为我们带来全新的方法fresh breath。PyPA 正在积极开发 warehouse其目的是完全替代当前的 PyPI 实现。这将是打包历史上迈出的一大步因为 PyPI 是如此古老且被忽视的项目我们中只有少数人可以想象逐步改进这个项目而不用完全重新编写。工具推荐Python 打包用户指南有关使用包的推荐工具给出了一些建议。这些工具大体可分为两组用于安装包的工具和用于包的创建与分发的工具。PyPA 推荐的第一组实用工具已经在第 1 章提到过但为了保持一致性我们这里将其再次列出。• 使用 pip 安装来自 PyPI 的包。• 将 virtualenv 或 venv 用于 Python 环境的应用级隔离。在 Python 打包用户指南中推荐包的创建与分发的工具如下。• 使用 setuptools 来定义项目并创建源代码发行版source distributions。• 使用 wheel 而不是 egg 来创建构建发行版built distributions。• 使用 twine 向 PyPI 上传包的发行版。项目配置很显然组织大型应用的代码的最简单方法是将其分成几个包。这使得代码更加简单也更容易理解、维护和修改。这样也使每个包的可复用性最大化。它们的作用就像组件一样。setup.py对于一个需要被分发的包来说其根目录包含一个 setup.py 脚本。它定义了distutils 模块中描述的所有元数据并将其合并为标准的 setup()函数调用的参数。虽然 distutils 是一个标准库模块但建议你使用 setuptools 包来代替它对标准的distutils 做了一些改进。因此这个文件的最少内容如下from setuptools import setupsetup(name‘mypackage’,)name 给出了包的全名。该脚本提供了一些命令你可以用–help-commands 选项列出以下这些命令$ python3 setup.py --help-commandsStandard commands:build build everything needed to installclean clean up temporary files from ‘build’ commandinstall install everything from build directorysdist create a source distribution (tarball, zip file)register register the distribution with the PyPbdist create a built (binary) distributioncheck perform some checks on the packageupload upload binary package to PyPIExtra commands:develop install package in ‘development mode’alias define a shortcut to invoke one or more commandstest run unit tests after in-place buildbdist_wheel create a wheel distributionusage: setup.py [globalopts] cmd1 [cmd1opts] [cmd2 [cmd2_opts] …]or: setup.py --help [cmd1 cmd2 …]or: setup.py --help-commandsor: setup.py cmd --help实际的命令列表更长而且会根据 setuptools 的可用扩展而变化。这里截取的命令都是最重要的而且和本章相关的。Standard commands标准命令是 distutils 提供的内置命令而 Extra commands额外命令则是由诸如 setuptools 这样的第三方包或任何其他定义并注册一个新命令的包所创建的。由另一个包注册的一个额外命令就是wheel 包提供的 bdist_wheel。