python中whl文件封裝的實(shí)現(xiàn)示例
一、Whl 包簡(jiǎn)介
Wheel(.whl)是 Python 的一種內(nèi)置包格式,用于替代傳統(tǒng)的 egg 格式。它被設(shè)計(jì)為更快速安裝的替代方案,具有以下優(yōu)點(diǎn):
- 安裝速度快:預(yù)編譯格式,無(wú)需在安裝時(shí)執(zhí)行 setup.py
- 更可靠:避免了執(zhí)行任意代碼的風(fēng)險(xiǎn)
- 支持二進(jìn)制分發(fā):可以包含編譯的擴(kuò)展文件
- 現(xiàn)代標(biāo)準(zhǔn):是當(dāng)前 Python 包分發(fā)的推薦格式
二、準(zhǔn)備工具包
制作whl包需要依賴相應(yīng)的工具包,安裝方法如下:
pip install setuptools wheel twine
- setuptools:用來(lái)打包你的項(xiàng)目,定義項(xiàng)目信息(名字、版本、依賴等)并生成分發(fā)文件(如 .whl 或 .tar.gz)。
- wheel:一種高效的包格式(.whl 文件),安裝快、無(wú)需編譯,setuptools 用它來(lái)生成這種包。
- twine:安全地將打包好的文件(.whl 或 .tar.gz)上傳到 PyPI 或私有倉(cāng)庫(kù)。
三、詳細(xì)制作流程
為了方便演示,創(chuàng)建了一個(gè)加減乘除的方法例子來(lái)演示。
1、創(chuàng)建目錄結(jié)構(gòu)
simple_math/ ├── src/ #源碼頂層目錄 │ └── simple_math/ #但功能模塊目錄 │ ├── __init__.py │ ├── add.py #加法 │ ├── sub.py #減法 │ ├── mult.py #乘法 │ └── div.py #除法 ├── test/ │ └── test_ops.py #測(cè)試程序 ├── examples/ │ └── example.py #使用示例程序 ├── README.md #說(shuō)明文檔 ├── LICENSE #許可證 ├── pyproject.toml # └── setup.py #打包配置文件
2、編寫包代碼
- add.py文件:
def add(a: float, b: float) -> float:
"""
將兩個(gè)數(shù)字相加
Args:
a (float): 第一個(gè)數(shù)字
b (float): 第二個(gè)數(shù)字
Returns:
float: 兩個(gè)數(shù)字的和
"""
return float(a + b)- sub.py 文件:
def sub(a: float, b: float) -> float:
return float(a - b)- mult.py 文件:
def mult(a: float, b: float) -> float:
return float(a * b)- div.py 文件:
def div(a: float, b: float) -> float:
"""
將第一個(gè)數(shù)字除以第二個(gè)數(shù)字
Args:
a (float): 被除數(shù)
b (float): 除數(shù)
Returns:
float: 兩個(gè)數(shù)字的商
Raises:
ZeroDivisionError: 當(dāng)除數(shù)為零時(shí)拋出
"""
if b == 0:
raise ZeroDivisionError("除數(shù)不能為零")
return float(a / b)- src/simple_math/__init__.py文件:
""" 簡(jiǎn)單數(shù)學(xué)計(jì)算包 提供加減乘除基本運(yùn)算 """ __version__ = "0.1.0" __author__ = "your_name <your.email@example.com>" # 導(dǎo)入所有功能,方便用戶直接使用 from .add import add from .sub import sub from .mult import mult from .div import div
3、(可選)編寫測(cè)試代碼
- test.py文件:
import pytest
from simple_math.add import add
from simple_math.sub import sub
from simple_math.mult import mult
from simple_math.div import div
class TestAdd:
"""測(cè)試加法功能"""
def test_add(self):
assert add(2, 3) == 5.0
class TestSub:
"""測(cè)試減法功能"""
def test_sub(self):
assert sub(5, 3) == 2.0
class TestMult:
"""測(cè)試乘法功能"""
def test_mult_positive_numbers(self):
assert mult(2, 3) == 6.0
class TestDiv:
"""測(cè)試除法功能"""
def test_div(self):
assert div(6, 3) == 2.0
def test_div_by_zero(self):
with pytest.raises(ZeroDivisionError):
div(5, 0)4、(可選)創(chuàng)建示例使用代碼
#!/usr/bin/env python3
from simple_math import add, sub, mult, div
def main():
"""演示所有功能的使用"""
print("=== math_ops 包使用示例 ===\n")
# 演示數(shù)學(xué)運(yùn)算
print("數(shù)學(xué)運(yùn)算:")
print(f"2 + 3 = {add(2, 3)}")
print(f"5 - 3 = {sub(5, 3)}")
print(f"2 * 3 = {mult(2, 3)}")
print(f"6 / 3 = {div(6, 3)}")
print("\n" + "="*40 + "\n")
# 演示錯(cuò)誤處理
print("錯(cuò)誤處理:")
try:
result = divide(5, 0)
print(f"5 / 0 = {result}")
except ZeroDivisionError as e:
print(f"錯(cuò)誤: {e}")
if __name__ == "__main__":
main()5、(關(guān)鍵)配置打包信息
pyproject.toml 和 setup.py 都是用于配置和打包 Python 項(xiàng)目的工具,但它們代表了不同的打包標(biāo)準(zhǔn)和時(shí)代。主要區(qū)別如下:
| 特性 | setup.py | pyproject.toml |
|---|---|---|
| 出現(xiàn)時(shí)間 | 早期(distutils/setuptools 時(shí)代) | 較新(PEP 518 及以后) |
| 格式 | Python 腳本 | TOML 配置文件 |
| 可執(zhí)行性 | 可執(zhí)行代碼,靈活性高但易濫用 | 聲明式配置,更安全 |
| 依賴管理 | 通常寫在 setup.py 或 requirements.txt 中 | 可直接在 pyproject.toml 中聲明依賴 |
| 構(gòu)建系統(tǒng)指定 | 默認(rèn)使用 setuptools | 顯式指定構(gòu)建后端(如 setuptools, poetry, flit 等) |
| 標(biāo)準(zhǔn)支持 | 傳統(tǒng)方式,逐漸被替代 | 當(dāng)前推薦方式(現(xiàn)代 Python 打包標(biāo)準(zhǔn)) |
方式一:使用 pyproject.toml(推薦方式)
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "simple-math"
version = "0.1.0"
description = "一個(gè)簡(jiǎn)單的數(shù)學(xué)計(jì)算"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "your_name", email = "your.email@example.com"}
]
keywords = ["math", "calculator", "hello-world", "example"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Education",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Education",
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = []
[project.urls]
Homepage = "https://github.com/yourusername/simple-math"
Documentation = "https://github.com/yourusername/simple-math#readme"
Repository = "https://github.com/yourusername/simple-math"
Issues = "https://github.com/yourusername/simple-math"
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
# 配置測(cè)試命令
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v"方式二:傳統(tǒng)的 setup.py 方式(可選)
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="simple-math",
version="0.1.0",
author="your_name",
author_email="your.email@example.com",
description="一個(gè)簡(jiǎn)單的數(shù)學(xué)計(jì)算",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourusername/simple-math",
package_dir={"": "src"},
packages=find_packages(where="src"),
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Education",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Education",
"Topic :: Software Development :: Libraries :: Python Modules",
],
python_requires=">=3.8",
install_requires=[],
extras_require={
"dev": ["pytest>=7.0", "twine>=4.0"],
},
)6、編寫文檔和許可文件
- README.md
創(chuàng)建一個(gè)詳細(xì)的 README 文件:
# 簡(jiǎn)單數(shù)學(xué)計(jì)算包 (simple-math) 一個(gè)簡(jiǎn)單的Python包,提供基本的數(shù)學(xué)運(yùn)算。 ## 功能 - **加法**: 將兩個(gè)數(shù)字相加 - **減法**: 從第一個(gè)數(shù)字中減去第二個(gè)數(shù)字 - **乘法**: 將兩個(gè)數(shù)字相乘 - **除法**: 將第一個(gè)數(shù)字除以第二個(gè)數(shù)字(含錯(cuò)誤處理) ## 安裝 pip install simple-math
- LICENSE文件
選擇一個(gè)合適的開(kāi)源許可證,如MIT:
MIT License Copyright (c) 2023 <your_name> 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.
7、構(gòu)建 Wheel 包
現(xiàn)在一切準(zhǔn)備就緒,可以構(gòu)建 wheel 包了。
# 確保你在項(xiàng)目根目錄(有pyproject.toml的目錄) cd simple_math # 使用現(xiàn)代構(gòu)建工具(推薦) python -m build --wheel # 或者使用傳統(tǒng)方式 python setup.py bdist_wheel
8、本地安裝和運(yùn)行測(cè)試
# 安裝wheel包 pip install dist/simple_math-0.1.0-py3-none-any.whl # 測(cè)試安裝是否成功 python -c "import simple_math; print(simple_math.__version__)" # 運(yùn)行測(cè)試 pip install pytest pytest
安裝:pip install <模塊名>
卸載:pip uninstall <模塊名>
結(jié)果:

四、擴(kuò)展:發(fā)布到 PyPI
1、創(chuàng)建 PyPI 賬戶
首先,在 PyPI 和 TestPyPI 上注冊(cè)賬戶。
2、安裝 twine
pip install twine
3、上傳到 TestPyPI
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
4、從 TestPyPI 安裝測(cè)試
pip install --index-url https://test.pypi.org/simple/ simple-math
5、上傳到正式 PyPI
twine upload dist/*
參考
到此這篇關(guān)于python中whl文件封裝的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)python whl文件封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
numpy中以文本的方式存儲(chǔ)以及讀取數(shù)據(jù)方法
今天小編就為大家分享一篇numpy中以文本的方式存儲(chǔ)以及讀取數(shù)據(jù)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
Python中的Socket 與 ScoketServer 通信及遇到問(wèn)題解決方法
Socket有一個(gè)緩沖區(qū),緩沖區(qū)是一個(gè)流,先進(jìn)先出,發(fā)送和取出的可自定義大小的,如果取出的數(shù)據(jù)未取完緩沖區(qū),則可能存在數(shù)據(jù)怠慢。本文通過(guò)實(shí)例代碼給大家介紹Python中的Socket 與 ScoketServer 通信及遇到問(wèn)題解決方法 ,需要的朋友參考下吧2019-04-04
Python+Opencv實(shí)戰(zhàn)之人臉追蹤詳解
人臉處理是人工智能中的一個(gè)熱門話題,人臉處理可以使用計(jì)算機(jī)視覺(jué)算法從人臉中自動(dòng)提取大量信息。本文將展示OpenCV Python實(shí)現(xiàn)人臉追蹤的示例代碼,需要的可以參考一下2021-11-11
解決python存數(shù)據(jù)庫(kù)速度太慢的問(wèn)題
這篇文章主要介紹了解決python存數(shù)據(jù)庫(kù)速度太慢的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
利用Python的pandas數(shù)據(jù)處理包將寬表變成窄表
這篇文章主要介紹了利用Python的pandas數(shù)據(jù)處理包將寬表變成窄表,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
利用python實(shí)現(xiàn)凱撒密碼加解密功能
這篇文章主要介紹了利用python實(shí)現(xiàn)凱撒密碼加解密功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03

