我写Python代码,并想在自己的电脑上把它安装成一个软件包。没想到这个过程会这么复杂。这里记录了我解决这个问题的方法。
为了保持这份文档简短,我会专注于我的用例。我想要创建一个名为“adder”(package)的包,该终端命令的基础是“adder”,该命令的调用方式如下所示:
adder [数字...]"(其中"adder"是一个命令或函数名)
该命令会运行并显示这样的总和,如下。
输入命令:adder 1 2 3
输出结果:6.0
它提供了一个可供使用的 API。这里是一个使用 API 的例子。这个 API 可以在其他 Python 模块中使用。
from adder import api
print(api.sum('1', '2', '3')) # 输出结果为6
我的系统运行的是MacOS 15.3,我的Python版本是3.13.2(这是最新的稳定版本)。我目前没有使用Python虚拟环境。这里仅讨论MacOS,但类似的方法可能也适用于Windows和Linux系统。此工作流程假设你还没有创建任何包的代码或存放项目资源的目录。
包是通过 Python 的 pip 命令安装的。要使用它,你可以输入 python3 -m pip
[参数...]。通过运行 python3 -m pip
可以确保你使用的是随 Python 安装的 pip 版本。
为了开始,我们需要一些术语。Python 模块是指以 .py
结尾,包含 Python 源代码的文件。Python 包是指包含文件 __init__.py
和至少一个其他文件的目录,即 Mac OS 中的文件夹。包的概念很重要,因为 pip
只会安装包。
Python 已经存在了很多年,毫不奇怪地,它的打包系统也已经进化了。现在的 pip
大部分功能依赖于子系统。这意味着我们需要选择一个子系统。我选择了 Hatch
,因为它正在积极开发,而且已经被广泛使用。它不仅是一个安装工具,官方称它是“一个现代且可扩展的 Python 项目管理器。”按照这些说明操作,你暂时不需要知道更多。以后你可以访问 https://github.com/pypa/hatch 了解更多 hatch
的功能和用途。
总之,这些说明是为在 MacOS 15.3 上使用 Python 3.12.2,并结合 hatch
项目管理器和 pyproject.toml
方法设计的。(你可以选择使用 setup.py
文件而不是 pyproject.toml
,不过这里不包括这部分内容。)
要开始,请安装Hatch。你可以使用pip
来安装,像如下所示:
pip install hatch
$ python3 -m pip install hatch # 这条命令用于安装hatch工具
在运行该命令之后,你可以验证Hatch是否已经安装成功。
运行此命令来查看hatch的版本号:
$ hatch --version
我的版本是1.14.0,但你可能得到的版本会更晚一些。
现在,你需要创建一个目录,你的项目将放在这里。本笔记的演示目录是“2513-htcreatepackages”。使用Hatch来创建目录结构,可以通过Finder或终端创建目录,然后切换到该目录下并运行Hatch的new
命令。该命令会创建其他Hatch命令期望的文件和文件夹。包名不能包含空格,只能包含字母和“-”和“_”字符。这是我输入并看到的结果:
$ cd Dropbox
$ cd rel-roy-lowrance # 这是存放这类项目的文件夹
$ mkdir 2518-htcreatepackages # 这是我开始的第18个项目,编号为2025年的2518
$ cd 2518-htcreatepackages
$ hatch new adder # 创建一个新的adder项目
执行 hatch new adder
后,你可能会看到以下输出,这类似于你先运行了 hatch
命令,然后再运行 tree
命令看到的内容。
adder
├── src
│ └── adder
│ ├── __about__.py
│ └── __init__.py
├── tests
│ └── __init__.py
├── LICENSE.txt
├── README.md
└── pyproject.toml
哈奇为你创建的包的目录是“adder”,这个目录的顶层包含以下项目:
- 目录
adder/src
是你源代码存放的地方。模块(Python 源代码文件)放在adder/src/adder
目录下。多个嵌套的同名文件夹会有点让人摸不着头脑,但这是一种约定。Hatch 创建了两个文件。我之后会专门解释这两个文件。 - 目录
adder/tests
是你的测试代码存放的地方。你可以通过运行hatch test
来测试你的代码,它会去adder/tests
里找并运行测试用例。这里我们不谈测试相关的内容。 - 文件
adder/LICENSE.txt
定义了代码的许可协议。在示例中,我用的是 MIT 协议。 - 文件
adder/README.md
提供了包的文档。它有一些现成的 Markdown 文本,你可以后续修改。 - 文件
pyproject.toml
指导我们使用的 Python 包安装程序pip
如何安装你的包。你得修改它。我会在后面告诉你怎么改。
目录 adder/src/adder
包含由 Hatch 创建的两个文件。
- 文件
adder/src/adder/__about__.py
定义了变量__version__
,其中包含包的版本号。在开发代码过程中,您需要使用语义化版本号来更新该值。您可以在 https://semver.org/ 了解更多关于语义化版本号的信息。 - 文件
__init__.py
不包含任何可执行语句,仅包含注释。该文件用于告知 Python 解释器此目录包含一个包。
咱们来规划一下如何把源代码文件加到 adder/src/adder
。
- 文件
adder/src/adder/api.py
将包含供其他 Python 程序使用的 API。 - 文件
adder/src/adder/run.py
将包含主程序。它将调用该 API。该模块包含一个main()
函数,作为程序的入口。
现在让我们修改 adder/project.toml
文件,使开发过程更简单。打开文件,你会看到由 Hatch 生成的多条语句。我们需要添加一个部分来,以便告诉 Python 安装工具该命令的名称以及在调用该命令时要启动的模块和函数。
打开 pyproject.toml
文件,滚动到末尾,在末尾添加这些行:
[项目脚本]
adder.run:main
我们将使用名为 adder
的命令,并通过在 run.py
文件中调用 main
函数来运行。需要注意的是,请使用点而不是斜杠:例如,adder = "adder/run:main"
这样的写法是无效的。
创建一个名为 api.py
的文件,并在其中输入以下代码。
# 返回字符串转换成浮点数后的总和
# *args: 字符串组成的可变数量的参数列表
def sum(*args: list[str]) -> float:
# sofar: 当前累加的浮点数结果
def iter(args, sofar: float) -> float:
# 迭代计算字符串转换成浮点数后的总和
if len(args) == 0:
return sofar
return iter(args[1:], sofar + float(args[0]))
return iter(args, 0.0)
创建一个名为 run.py
的文件,并在其中输入以下代码。
# adder 包的主要程序如下
import argparse
from . import api
def 获取参数():
parser = argparse.ArgumentParser()
parser.add_argument('values', nargs='*')
return parser.parse_args()
def 主函数():
args = 获取参数()
print(api.sum(*args.values))
if __name__ == '__main__':
# 当脚本直接运行时
主函数()
我们差不多准备好了开始测试。为此,请打开终端,切换到最顶层的 adder
文件夹,然后输入以下命令:
ls # => LICENSE.txt (许可证) README.md (读我文档) pyproject.toml (项目配置文件) src (源代码目录) tests (测试目录)
python3 -m pip install -e . # 安装当前目录的开发版本
你不需要用 ls
命令。这里提到它只是为了帮助你理解指示。遵循指示。
选项 -e
告诉安装程序创建一个可编辑安装。这个选项或许应该叫做“可编辑”安装(因为字母“e”的缘故)。如果你编辑了源代码,可以重新运行安装命令而无需再运行一次 pip install
。这样可以让你的开发循环更紧凑。
在运行 pip install
命令后,你可以在终端中使用你的命令:命令名。例如,如果命令名是 my_command
,则可以这样使用。
adder 1 2
3.0
注释:这里的命令adder 1 2
是将数字1和2相加,结果为3.0。这个输出表示两个数字相加后的结果。
你也希望能够在其他 Python 代码中使用 API。
在顶级的 adder
目录中输入此代码,不过你也可以把它放在系统的任何位置。我用的是 use_api.py
,但你也可以用任何名字。
from adder import api
print(api.sum('1', '2'))
运行新模块并检查API是否被调用:
python3 use_api.py
版本号 3.0
现在你有了一个可用的例子,你可以把它存起来,然后开始新的项目时克隆它。你可以这样做:创建一个本地 Git 仓库,然后推送到 GitHub 上新创建的仓库里。
参考书目(附注释)
GitHub.com. “创建一个仓库。”网址: https://docs.github.com/en/repositories/creating-and-managing-repositories/quickstart-for-repositories. 最后访问日期:2025年2月25日.
按照这里的说明操作,但不要创建 README,因为你已经按照这里说明创建了一个 README 文件。创建仓库,然后按照仓库页面上提供的进一步的 GitHub 指示操作。
Hatch。"Hatch 是一个现代和高度可扩展的 Python 项目管理器。" URL: https://github.com/pypa/hatch。引用日期:2025–02–25
pip install
命令很大程度上依赖于插件来完成其工作。Hatch 是一个流行的插件,不仅提供pip install
所需的后端能力,还提供了更多功能。
pip 安装文档。 “pip install” URL: https://pip.pypa.io/en/stable/cli/pip_install/。2025年2月25日访问。
pip install
命令用于从 PyPI(全球 Python 包索引)和其他来源(如你本地项目文件夹)安装 Python 包。我发现文档很难理解,部分原因是pip install
功能已经显著变化,而一些不再推荐使用的功能仍然保留。
pyOpenSci. "让你的Python代码变得可安装。" URL: https://www.pyopensci.org/python-package-guide/tutorials/installable-code.html,2025–02–14访问。
本页面说明了如何使用Hatch来创建一个包,并使其在您的机器上运行。它比这个解释更长,部分原因是它包含更多内容。
rlowrance. “adder.” https://github.com/rlowrance/adder. 访问时间:2025年02月25日。
这是我为这个项目创建的GitHub仓库。
Semver.org. “语义化版本 2.0.0.” URL: https://semver.org/. 访问时间:2025年2月25日。
现代包管理工具使用语义版本来跟踪可安装软件的修订并指定代码库依赖关系。语义版本号的格式为MAJOR.MINOR.PATCH,例如,1.2.3。
共同学习,写下你的评论
评论加载中...
作者其他优质文章