Python程序打包指南:手把手教你一步步完成

最近感兴趣想将开发的项目转成Package,研究了一下相关文章,并且自己跑通了,走了一下弯路,这里记录一下如何打包一个简单的Python项目,展示如何添加必要的文件和结构来创建包,如何构建包,以及如何将其上传到Python包索引(PyPI)。

首先要确保安装最新版本:

# Unix/macOS
python3-m pip install--upgrade pip

# windows
py-m pip install--upgrade pip

一个简单的项目

本教程使用一个名为example_package_YOUR_USERNAME_HERE的简单项目。如果你的用户名是me,那么包将会是example_package_me;另外确保有一个唯一的包名,不会与遵循本教程的其他人上传的包冲突。建议在打包自己的项目之前,按照本教程的原样使用这个项目。

在本地创建以下文件结构:

packaging_tutorial/
└── src/
    └── example_package_YOUR_USERNAME_HERE/
        ├── __init__.py
        └── example.py

包含Python文件的目录应该与项目名称匹配。这简化了配置,对于安装包的用户来说更加明显。

__init__. py是将目录导入为包所必需的,即使在本教程中,该文件是空的。

example.py是包内模块的示例,该模块可能包含包的逻辑(函数、类、常量等)。打开该文件并输入以下内容:

def add_one(number):
    return number + 1

创建此结构后,需要在packaging_tutorial目录中运行本教程中的所有命令。

创建包文件

现在将添加用于准备项目以进行分发的文件。完成后,项目结构将如下所示:

packaging_tutorial/
├── LICENSE
├── pyproject.toml
├── README.md
├── src/
│   └── example_package_YOUR_USERNAME_HERE/
│       ├── __init__.py
│       └── example.py
└── tests/

创建测试目录

test/是测试文件的占位符,这里暂时将其留空。

选择构建后端

像pip和build这样的工具实际上不会将源代码转换为分发包(如轮子);该工作由构建后端执行。构建后端决定您的项目将如何指定其配置,包括元数据(有关项目的信息,例如,PyPI上显示的名称和标签)和输入文件。构建后端具有不同级别的功能,例如它们是否支持构建扩展模块,应该选择适合需求和偏好的一个。

这里可以从许多后端中进行选择;本教程默认使用Hatchling,但它将与支持元数据的setuptools、Flight、PDM和其他支持[project]表的方法相同。

pyproject.toml告诉构建前端工具,如pip和build,为项目使用哪个后端。以下是一些常见构建后端的示例,但请查看后端自己的留档以获取更多详细信息。

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[build-system]
requires = ["flit_core>=3.4"]
build-backend = "flit_core.buildapi"

[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"

requires键是构建包所需的包列表。前端应该在构建包时自动安装它们。前端通常在隔离的环境中运行构建,因此在这里省略依赖项可能会导致构建时错误。这应该始终包括后端的包,并且可能有其他构建时依赖项。

build-backend键是前端用来执行构建的Python对象的名称。

这两个值都将由构建后端的留档提供,或者由其命令行界面生成,不需要自定义这些设置。

构建工具的其他配置将在pyproject.toml工具部分或构建工具定义的特殊文件中。例如,当使用setuptools作为构建后端时,可以将其他配置添加到setup.pysettings.cfg文件,并指定setuptools。build_meta在构建中允许工具自动定位和使用这些。

配置元数据

打开pyproject.toml并输入以下内容。更改name以包含用户名;这可确保拥有唯一的包名,不会与遵循本教程的其他人上传的包冲突。

[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
  { name="Example Author", email="author@example.com" },
]
description = "A small example package"
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

[project.urls]
"Homepage" = "https://github.com/pypa/sampleproject"
"Bug Tracker" = "https://github.com/pypa/sampleproject/issues"
  • name是包的分发名称。它可以是任何名称,只要它只包含字母、数字、._-。它也不能已经在PyPI上使用。在本教程中,请务必使用自己的用户名更新它,因为这可以确保不会尝试上传与已存在的名称相同的包。
  • version是包版本。有关版本的更多详细信息,请参阅版本说明符规范。一些构建后端允许以其他方式指定它,例如从文件或git tag。
  • authors用于标识包的作者;可以为每个作者指定姓名和电子邮件。还可以以相同的格式列出maintainers
  • description是对包装的简短的一句话总结。
  • readme是包含包的详细描述的文件的路径。这显示在PyPI上的包详细信息页面上。在这种情况下,描述是从README.md加载的(这是一种常见的模式)。项目元数据规范中还有一种更高级的表格形式。
  • requires-python提供项目支持的Python版本。像pip这样的安装程序会回顾旧版本的包,直到找到一个具有匹配Python版本的包。
  • classifiers提供有关包的索引和pip一些附加元数据。在这种情况下,包仅与Python3兼容,根据MIT许可证获得许可,并且OS独立。您应该始终至少包括包适用于Python的哪个版本,包在哪个许可证下可用,以及包将适用于哪些操作系统。有关分类器的完整列表,请参阅https://pypi.org/classifiers/。
  • URL允许列出要在PyPI上显示的任意数量的额外链接。通常这可能是指向源、留档、问题跟踪器等。

有关可以在[project]表中定义的这些和其他字段的详细信息,请参阅项目元数据规范。其他常见字段是提高可发现性的关键字和安装包所需的依赖项

创建README.md

打开README.md并输入以下内容,也可以自定义此内容。

# Example Package

This is a simple example package. You can use
[GitHub-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

创建LICENSE

上传到Python包索引的每个软件包都必须包含许可证。这将告诉安装软件包的用户他们可以使用上传软件包的条款。有关选择许可证的帮助,请参阅https://choosealicense.com/。选择许可证后,打开`LICENSE`并输入许可证文本。例如,如果选择了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.

大多数构建后端会自动在包中包含许可证文件。有关详细信息,请参阅后端的留档。

包括其他文件

上面列出的文件将自动包含在源发行版中。如果想包含其他文件,请参阅构建后端的留档。

生成分发档案

下一步是为包生成分发包。这些是上传到Python包索引的存档,可以通过pip安装。确保安装了最新版本的PyPA bulid:

# Unix/macOS
python3 -m pip install --upgrade build

# Windows
py -m pip install --upgrade build

现在从pyproject. toml所在的同一目录运行下面的命令:

# Unix/macOS
python3 -m build

# Windows
py -m build

这个命令应该输出很多文本,一旦完成应该在dist目录中生成两个文件:

dist/
├── example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
└── example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz

tar.gz文件是源发行版,而.whl文件是构建发行版。较新的pip版本优先安装构建发行版,但如果需要可以回退到源发行版。应该始终上传源发行版,并为项目兼容的平台提供构建发行版。在这种情况下,本文的示例包与任何平台上的Python兼容,因此只需要一个构建发行版。

上传分发档案

最后将打好的包上传到Python包索引,可供其它人安装。需要做的第一件事是在TestPyPI上注册一个帐户,这是一个用于测试和实验的包索引的单独实例。对于像本教程这样不一定想上传到真实索引的东西,这样的测试环境是非常好的。

首先要注册一个帐户,打开https://test.pypi.org/account/register/并完成该页面上的步骤。还需要在能够上传任何包之前验证填写的电子邮件地址。有关更多详细信息,请参阅[使用TestPyPI](https://packaging.python.org/en/latest/guides/using-testpypi/)。

要安全地上传项目,还需要一个PyPIAPI令牌。https://test.pypi.org/manage/account/#api-tokens创建一个,将“范围”设置为“整个帐户”。**在复制并保存令牌之前不要关闭页面——您将不会再看到该令牌。**

这一步需要QR扫描二维码,得到6位数字验证码,另外获得的令牌如何使用呢?这是踩的弯路,详细说一下:

PyPi 调整了安全策略,不再允许启用两步验证的账号使用用户名密码来上传项目了,必须使用 API 令牌来进行身份验证。登录 PyPi ,进入账户设置页,点击「添加 API 令牌」按钮创建 API 令牌。然后修改 ~/.pypirc 配置文件, 用户名字段改为 __token__ ,密码字段改为刚才创建的令牌:

[testpypi]
  username = __token__
  password = pypi-AgENdGVzdC5weXBpLm9xxxxxxxxxxxxxxx

注册好之后就可以使用twine上传分发包。上传之前需要先安装Twine:

# Unix/macOS
python3 -m pip install --upgrade twine

# Windows
py -m pip install --upgrade twine

安装后,运行Twine上传dist下的所有存档:

# Unix/macOS
python3 -m twine upload --repository testpypi dist/*

# Windows
py -m twine upload --repository testpypi dist/*

命令完成后,您应该会看到类似于以下内容的输出:

Uploading distributions to https://test.pypi.org/legacy/
Enter your username: __token__
Uploading example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.2/8.2 kB • 00:01 • ?
Uploading example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.8/6.8 kB • 00:00 • ?

上传后,打的包应该可以在TestPyPI上查看;例如:https://test.pypi.org/project/example_package_YOUR_USERNAME_HERE

在这里插入图片描述

安装新上传的包

上传成果后,可以使用pip安装包并验证它是否有效。创建一个虚拟环境并从TestPyPI安装上传的包:

# Unix/macOS
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-package-YOUR-USERNAME-HERE

# Windows
py -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-package-YOUR-USERNAME-HERE

pip应该从TestPyPI安装包,输出应该如下所示:

Collecting example-package-YOUR-USERNAME-HERE
  Downloading https://test-files.pythonhosted.org/packages/.../example_package_YOUR_USERNAME_HERE_0.0.1-py3-none-any.whl
Installing collected packages: example_package_YOUR_USERNAME_HERE
Successfully installed example_package_YOUR_USERNAME_HERE-0.0.1

注 此示例使用--index-url标志来指定TestPyPI而不是live PyPI。此外,它还指定--no-deps。由于TestPyPI没有与live PyPI相同的软件包,因此尝试安装依赖项可能会失败或安装意外的东西。虽然我们的示例包没有任何依赖项,但在使用TestPyPI时避免安装依赖项是一个很好的做法。

接下来就可以通过导入软件包来测试它是否已正确安装。确保仍在虚拟环境中,然后运行Python:

from example_package_YOUR_USERNAME_HERE import example

example.add_one(2)
# 3

后续

恭喜,已成果打包并分发了一个Python项目!

请记住,本教程展示了如何将包上传到Test PyPI,这不是永久存储。Test系统偶尔会删除包和帐户。最好像本教程一样使用TestPyPI进行测试和实验。

当准备好将真实包上传到Python包索引时,可以像本教程中一样执行相同的操作,但有以下重要区别:

  • 为包选择一个难忘且独特的名称;
  • 在https://pypi.org上注册一个帐户,这是两个独立的服务器,测试服务器的登录详细信息不与主服务器共享;
  • 使用twine上传dist/*上传自己的包,并输入正式PyPI环境上注册的帐户的凭据。在生产环境中上传包,不需要指定--repository;默认情况下,包将上传到https://pypi.org/;
  • 使用python3-m pip install[your-package]从真正的PyPI安装包;

参考

  • Hattch

  • Flit

  • pdm

  • poetry

  • PEP517

  • PEP518

  • https://segmentfault.com/a/1190000008663126

  • Packaging binary extensions]

  • https://www.fournoas.com/posts/authentication-on-pypi-using-api-token-instead-of-password/

  • https://packaging.python.org/en/latest/tutorials/packaging-projects/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/161764.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

纯CSS自定义滚动条样式

.my-carousel{height: 474px;overflow-y: auto; } /*正常情况下滑块的样式*/ .my-carousel::-webkit-scrollbar {width: 5px; } .my-carousel::-webkit-scrollbar-thumb {border-radius: 8px;background-color: #ccc; } .my-carousel::-webkit-scrollbar-track {border-radius:…

生活总是自己的,请尽情打扮,尽情可爱,,

同色系拼接羽绒服了解一下 穿上时尚感一下子就突显出来了 90白鸭绒填充,不仅时尚还保暖 设计感满满的羽绒服不考虑一下吗?

Git企业开发级讲解(四)

📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、理解分⽀二、创建分支三、切换分⽀四、合并分⽀五、删除分⽀六、合并冲突七、分⽀管理策略…

Windows10下Maven3.9.5安装教程

文章目录 1.下载maven2.安装3.配置系统变量3.1.新建系统变量 MAVEN_HOME3.2.编辑系统变量Path 4.CMD命令测试是否安装成功5.配置maven本地仓库6.配置国内镜像仓库 1.下载maven 官网 https://maven.apache.org/download.cgi 点击下载。 2.安装 解压到指定目录 D:\installSoft…

vue3基础学习

##以前怎么玩的? ###MVC Model:Bean View:视图 Controller ##vue的ref reactive ref:必须是简单类型 reactive:必须不能是简单类型 ###创建一个Vue项目 npm init vuelatest ###生命周期 ###setup相关 ####Vue2的一些写法 -- options API ####Vue3的写法 组合式API Vu…

深入理解ResNet网络:实现与应用

Resnet 在深度学习领域,卷积神经网络(CNN)是一种非常重要的模型,它在图像识别、目标检测等领域取得了显著的成果。然而,随着网络层数的增加,梯度消失和梯度爆炸问题变得越来越严重,导致训练深层…

OpenCV快速入门:图像滤波与边缘检测

文章目录 前言一、噪声种类与生成1.1 椒盐噪声1.2 高斯噪声1.3 彩色噪声 二、卷积操作2.1 卷积基本原理2.2 卷积操作代码实现 三、线性滤波3.1 均值滤波均值滤波原理均值滤波公式均值滤波代码实现 3.2 方框滤波方框滤波原理方框滤波公式方框滤波代码实现 3.3 高斯滤波高斯滤波原…

Matalab插值详解和源码

转载:Matalab插值详解和源码 - 知乎 (zhihu.com) 插值法 插值法又称“内插法”,是利用函数f (x)在某区间中已知的若干点的函数值,作出适当的特定函数,在区间的其他点上用这特定函数的值作为函数f (x)的近似值,这种方…

kernel32.dll下载地址分享,Kernel32.DLL文件丢失的修复指南

作为计算机用户,我们可能都曾遭遇过这样一条令人烦恼的错误信息: "程序无法启动,因为您的计算机中缺少Kernel32.dll"。在这种情况下,往往会引发一系列疑问: Kernel32.dll是什么?为什么它对我的电…

51.Sentinel微服务保护

目录 (1)初识Sentinel。 (1.1)雪崩问题及解决方案。 (1.1.1)雪崩问题。 (1.1.2)解决雪崩问题的四种方式。 (1.1.3)总结。 (1.2)…

c语言:模拟实现qsort函数

qsort函数的功能: qsort相较于冒泡排序法,不仅效率更快,而且能够比较不同类型的元素,如:浮点数,结构体等等。这里我们来模拟下qsort是如何实现这一功能的,方便我们对指针数组有一个更深层次的理…

【APUE】补充 — 基于管道的线程池

目录 一、引言 二、代码实现 三、思考 一、引言 在线程章节的 3.2 部分,我们曾经提到过线程池的实现 在当时的代码中,我们仅仅用的一个 int 类型的变量来表示这个“池”,用来存放任务 显然这个池太小了,如果下游线程很多&am…

代码随想录 Day49 单调栈01 LeetCode LeetCodeT739每日温度 T496 下一个最大元素I

前言 折磨的死去活来的动态规划终于结束啦,今天秋秋给大家带来两题非常经典的单调栈问题,可能你不清楚单调栈是什么,可以用来解决什么问题,今天我们就来一步一步的逐渐了解单调栈,到能够灵活使用单调栈.注意以下讲解中,顺序的描述为 从栈头到栈底的顺序 什么时候用单…

3D建模基础教程:编辑样条线【子层级】

了解子层级编辑样条线 在3D建模中,样条线是创建各种形状和曲线的重要工具。而编辑样条线是3D建模过程中不可或缺的一部分。今天,我们将一起学习如何编辑样条线,以及了解其子层级的相关知识。 样条线的子层级介绍 样条线的子层级包括&#xff…

Java的IO流-缓冲流

字节缓冲流 package com.itheima.d2;import java.io.*;public class Test1 {public static void main(String[] args) {try (InputStream is new FileInputStream("IO/src/itheima01.txt");//1、定义一个字节缓冲输入流包装原始的字节输入流InputStream bis new Bu…

任你五花八门预训练方法,我自监督学习依然能打!

长时间没看论文,外面已经发展成这样了? 以下都是新paper,挑了几个感兴趣的,一起粗略看看吧~ Battle of the Backbones: A Large-Scale Comparison of Pretrained Models across Computer Vision Tasks GitHub | https://github.…

linux基本指令总结--文件和目录

前言: 想要学好Linux操作系统,理解并熟悉一些基本的指令是必要的,下面我将整理出关于文件和目录操作的一些基本指令和用法,我的linux环境部署在服务器端,使用xshell软件进行远程操作。 本章指令整合: ls查…

十个一手app拉新地推拉新推广接单平台,放单/接任务渠道

做过地推拉新的朋友一定都非常清楚,app拉新推广一手接单平台,和非一手接任务平台之间的收益差,可以用天壤之别来形容。那么一手app拉新渠道应该怎么找?下面这十个常见的地推拉新app接单平台,一定要收藏。 1. 聚量推客…

学习c#的第十四天

目录 C# 接口(Interface) 接口的特点 定义接口 接口继承 接口和抽象类的区别 C# 命名空间(Namespace) using 关键字 定义命名空间 嵌套命名空间 C# 接口(Interface) 接口定义了所有类继承接口时应…