Python打包方法之setup.py與pyproject.toml的全面對(duì)比與實(shí)戰(zhàn)
一、setup.py 與 pyproject.toml 的區(qū)別
1. setup.py(傳統(tǒng)方式)
setup.py 是 Python 打包的傳統(tǒng)方法,使用 setuptools 或 distutils 定義包的元數(shù)據(jù)和依賴(lài)關(guān)系。典型示例如下:
from setuptools import setup
setup(
name='mypackage',
version='0.1',
packages=['mypackage'],
install_requires=['requests']
)
使用方法:
python setup.py sdist bdist_wheel pip install .
2. pyproject.toml(現(xiàn)代方式)
自 PEP 518 引入后,pyproject.toml 成為推薦的配置方式。它分離了構(gòu)建系統(tǒng)配置和包元數(shù)據(jù),支持多種構(gòu)建工具(如 setuptools、poetry 等)。示例:
[build-system] requires = ["setuptools>=42", "wheel"] build-backend = "setuptools.build_meta" [project] name = "mypackage" version = "0.1" dependencies = ["requests"]
使用方法:
pip install .
二、為什么推薦 pyproject.toml?
- 標(biāo)準(zhǔn)化與兼容性:符合最新打包標(biāo)準(zhǔn),與各種工具兼容性更好。
- 簡(jiǎn)化配置:分離構(gòu)建系統(tǒng)和元數(shù)據(jù),使配置更清晰。
- 多構(gòu)建系統(tǒng)支持:支持多種工具,提供更大靈活性。
- 安全性:減少對(duì)自定義腳本的依賴(lài),降低風(fēng)險(xiǎn)。
實(shí)際場(chǎng)景中的必要性
假設(shè)你正在開(kāi)發(fā)一個(gè)復(fù)雜的機(jī)器學(xué)習(xí)庫(kù),涉及多個(gè)依賴(lài)項(xiàng)和復(fù)雜的構(gòu)建步驟。使用 pyproject.toml 可以輕松定義這些需求,并確保在不同的開(kāi)發(fā)和部署環(huán)境中保持一致性。此外,許多現(xiàn)代工具(如 CI/CD 系統(tǒng))已經(jīng)內(nèi)置了對(duì) pyproject.toml 的支持,簡(jiǎn)化了自動(dòng)化流程。
構(gòu)建 Python 包的最佳實(shí)踐
- 新項(xiàng)目使用 pyproject.toml:對(duì)于新項(xiàng)目,推薦使用
pyproject.toml,以符合現(xiàn)代打包標(biāo)準(zhǔn)并提高兼容性。 - 舊項(xiàng)目逐步遷移:如果維護(hù)的是已有使用
setup.py的項(xiàng)目,可以繼續(xù)使用,但建議在可行時(shí)遷移到pyproject.toml。 - 結(jié)合使用:在某些情況下,可以同時(shí)使用
pyproject.toml和setup.py,例如用pyproject.toml處理大部分配置,而保留一個(gè)最小化的setup.py來(lái)處理特定功能(如構(gòu)建 C 擴(kuò)展)。 - 使用 setup.cfg:如果希望采用更聲明式的格式但仍使用
setup.py,可以考慮使用setup.cfg,將元數(shù)據(jù)放在配置文件中,邏輯保留在setup.py中。 - 利用構(gòu)建工具:使用如
Poetry或Flit等工具,可以簡(jiǎn)化依賴(lài)管理和打包流程,自動(dòng)管理pyproject.toml和其他相關(guān)文件的創(chuàng)建。
三、實(shí)戰(zhàn)示例:構(gòu)建和發(fā)布一個(gè)機(jī)器學(xué)習(xí)包
下面通過(guò)一個(gè)實(shí)際的機(jī)器學(xué)習(xí)項(xiàng)目示例,展示如何使用 pyproject.toml 構(gòu)建、測(cè)試和發(fā)布一個(gè) Python 包。
項(xiàng)目概述
我們將構(gòu)建一個(gè)名為 mlpredictor 的包,該包:
- 包含一個(gè)使用 scikit-learn 的簡(jiǎn)單分類(lèi)器模型。
- 提供訓(xùn)練模型和進(jìn)行預(yù)測(cè)的功能。
- 結(jié)構(gòu)化以便發(fā)布到 PyPI 和 GitHub。
步驟詳解
1. 創(chuàng)建項(xiàng)目結(jié)構(gòu)
mlpredictor/ │ ├── mlpredictor/ │ ├── __init__.py │ ├── model.py │ ├── tests/ │ ├── test_model.py │ ├── LICENSE ├── README.md ├── pyproject.toml └── .gitignore
2. 編寫(xiě)代碼
mlpredictor/model.py
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import pickle
class MLPredictor:
def __init__(self):
self.model = None
def train(self):
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
iris.data, iris.target, test_size=0.2, random_state=42
)
self.model = RandomForestClassifier()
self.model.fit(X_train, y_train)
def predict(self, data):
if not self.model:
raise Exception("Model is not trained yet!")
return self.model.predict([data])
def save_model(self, path="model.pkl"):
with open(path, "wb") as f:
pickle.dump(self.model, f)
def load_model(self, path="model.pkl"):
with open(path, "rb") as f:
self.model = pickle.load(f)
mlpredictor/*init*.py
from .model import MLPredictor __all__ = ["MLPredictor"]
3. 創(chuàng)建 pyproject.toml 文件
pyproject.toml
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mlpredictor"
version = "0.1.0"
description = "A simple machine learning package using scikit-learn"
authors = [
{name = "Ebrahim", email = "ebimsv0501@gmail.com"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.6"
dependencies = [
"scikit-learn>=1.0",
]
[project.urls]
"Homepage" = "https://github.com/xxx_your_account/mlpredictor"
[build-system]:指定構(gòu)建系統(tǒng)要求,這里使用setuptools和wheel。[project]:包含包的元數(shù)據(jù),如名稱(chēng)、版本、描述、作者、許可證、依賴(lài)項(xiàng)等。
4. 編寫(xiě)測(cè)試
使用 pytest 添加測(cè)試。
tests/test_model.py
import pytest
from mlpredictor import MLPredictor
def test_train_and_predict():
model = MLPredictor()
model.train()
result = model.predict([5.1, 3.5, 1.4, 0.2])
assert len(result) == 1
if __name__ == "__main__":
pytest.main()
5. 添加 README、License 和 .gitignore
README.md
# MLPredictor MLPredictor 是一個(gè)簡(jiǎn)單的機(jī)器學(xué)習(xí)包,使用 scikit-learn 訓(xùn)練 RandomForest 模型,并使用戶能夠進(jìn)行預(yù)測(cè)。該包旨在演示如何打包 Python 機(jī)器學(xué)習(xí)項(xiàng)目以供分發(fā)。 ## 特性 - 在 Iris 數(shù)據(jù)集上訓(xùn)練 RandomForestClassifier。 - 訓(xùn)練后對(duì)新數(shù)據(jù)進(jìn)行預(yù)測(cè)。 - 保存和加載訓(xùn)練好的模型。 ## 安裝 您可以通過(guò) **PyPI** 或從 **源代碼** 安裝該包。 ### 通過(guò) PyPI 安裝 ```bash pip install mlpredictor
通過(guò)源代碼安裝(GitHub)
git clone https://github.com/xxx_your_account/mlpredictor.git cd mlpredictor pip install .
使用方法
安裝后,可以使用 MLPredictor 訓(xùn)練模型并進(jìn)行預(yù)測(cè)。
示例:訓(xùn)練和預(yù)測(cè)
from mlpredictor import MLPredictor
# 初始化預(yù)測(cè)器
predictor = MLPredictor()
# 在 Iris 數(shù)據(jù)集上訓(xùn)練模型
predictor.train()
# 對(duì)樣本輸入進(jìn)行預(yù)測(cè)
sample_input = [5.1, 3.5, 1.4, 0.2]
prediction = predictor.predict(sample_input)
print(f"預(yù)測(cè)類(lèi)別: {prediction}")
LICENSE
可以選擇合適的開(kāi)源許可證,如 MIT License。
.gitignore
*.pyc __pycache__/ *.pkl dist/ build/
6. 本地測(cè)試包
通過(guò)以下命令安裝包:
pip install .
安裝后,運(yùn)行測(cè)試以確保一切正常:
pytest tests
注意:
如果使用
setup.py,它會(huì)讀取setup.py文件以收集包元數(shù)據(jù)和安裝信息,并解析和安裝指定的依賴(lài)項(xiàng)。如果使用
pyproject.toml,它會(huì)讀取該文件,可能指定構(gòu)建系統(tǒng)要求和配置。執(zhí)行上述命令后,通常會(huì)創(chuàng)建以下目錄:- Distribution Directory:可能是
build/、dist/或.eggs/目錄,具體取決于安裝過(guò)程以及是源碼安裝還是 wheel 安裝。 - build/:在構(gòu)建過(guò)程中創(chuàng)建,包含用于創(chuàng)建包的臨時(shí)文件。
- dist/:包含從包生成的構(gòu)建分發(fā)文件(如 wheel 文件)。
- egg-info/ 或 .egg-info/:包含有關(guān)已安裝包的元數(shù)據(jù),包括其依賴(lài)項(xiàng)和版本號(hào)。
- Distribution Directory:可能是
確保項(xiàng)目正常工作后,繼續(xù)后續(xù)步驟。
7. 推送到 GitHub
初始化 Git 倉(cāng)庫(kù)
git init git add . git commit -m "Initial commit"
創(chuàng)建 GitHub 倉(cāng)庫(kù)
前往 GitHub 并創(chuàng)建一個(gè)名為
mlpredictor的新倉(cāng)庫(kù)。推送代碼到 GitHub
git remote add origin https://github.com/xxx_your_account/mlpredictor.git git branch -M main git push -u origin main
注意:將
xxx_your_account替換為您的 GitHub 用戶名。
8. 發(fā)布到 PyPI
現(xiàn)在項(xiàng)目已經(jīng)設(shè)置并推送到 GitHub,可以將其發(fā)布到 PyPI。
安裝必要的工具
pip install twine build
構(gòu)建包
python -m build
這將在 dist/ 目錄下創(chuàng)建 .tar.gz 和 .whl 文件。檢查 dist/ 目錄,確保包含類(lèi)似以下文件:
mlpredictor-0.1.0-py3-none-any.whl mlpredictor-0.1.0.tar.gz
上傳到 PyPI
twine upload dist/*
您需要一個(gè) PyPI 賬戶才能上傳包。上傳成功后,其他人可以通過(guò)以下命令安裝您的包:
pip install mlpredictor
9. 安裝并使用包
通過(guò) pip 安裝后,可以在 Python 代碼中使用該包:
from mlpredictor import MLPredictor
predictor = MLPredictor()
predictor.train()
prediction = predictor.predict([5.1, 3.5, 1.4, 0.2])
print("Predicted class:", prediction.item())
# 輸出示例:
# Predicted class: 0
五、總結(jié)
在 Python 打包領(lǐng)域,setup.py 和 pyproject.toml 各有其重要性和適用場(chǎng)景。盡管 setup.py 在傳統(tǒng)項(xiàng)目中仍然發(fā)揮作用,但向 pyproject.toml 的轉(zhuǎn)變代表了 Python 社區(qū)向更安全、標(biāo)準(zhǔn)化實(shí)踐發(fā)展的趨勢(shì)。對(duì)于新項(xiàng)目,強(qiáng)烈建議采用 pyproject.toml,因?yàn)樗粌H簡(jiǎn)化了打包過(guò)程,還提高了與各種工具和庫(kù)的兼容性。
通過(guò)本文的實(shí)戰(zhàn)示例,您應(yīng)該能夠掌握如何使用 pyproject.toml 構(gòu)建、測(cè)試和發(fā)布一個(gè)功能完善的 Python 包。無(wú)論是個(gè)人項(xiàng)目還是團(tuán)隊(duì)協(xié)作,遵循這些最佳實(shí)踐將大大提升項(xiàng)目的可維護(hù)性和可擴(kuò)展性。
以上就是Python打包方法之setup.py與pyproject.toml的全面對(duì)比與實(shí)戰(zhàn)的詳細(xì)內(nèi)容,更多關(guān)于Python setup.py與pyproject.toml對(duì)比的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)跨域代理服務(wù)器的方法
這篇文章主要介紹了python實(shí)現(xiàn)跨域代理服務(wù)器的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
jupyter notebook 調(diào)用環(huán)境中的Keras或者pytorch教程
這篇文章主要介紹了jupyter notebook 調(diào)用環(huán)境中的Keras或者pytorch教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
python自動(dòng)化測(cè)試之從命令行運(yùn)行測(cè)試用例with verbosity
這篇文章主要介紹了python自動(dòng)化測(cè)試之從命令行運(yùn)行測(cè)試用例with verbosity,是一個(gè)較為經(jīng)典的自動(dòng)化測(cè)試實(shí)例,需要的朋友可以參考下2014-09-09
Python自動(dòng)生成代碼 使用tkinter圖形化操作并生成代碼框架
這篇文章主要為大家詳細(xì)介紹了Python自動(dòng)生成代碼,使用tkinter圖形化操作并生成代碼框架,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
python中import,from……import的使用詳解
這篇文章主要介紹了python中import,from……import的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
深入解析Python設(shè)計(jì)模式編程中建造者模式的使用
這篇文章主要介紹了深入解析Python設(shè)計(jì)模式編程中建造者模式的使用,建造者模式的程序通常將所有細(xì)節(jié)都交由子類(lèi)實(shí)現(xiàn),需要的朋友可以參考下2016-03-03
Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)篩選及提取序列中元素的方法
這篇文章主要介紹了Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)篩選及提取序列中元素的方法,涉及Python列表推導(dǎo)式、生成器表達(dá)式及filter()函數(shù)相關(guān)使用技巧,需要的朋友可以參考下2018-03-03
Numpy中轉(zhuǎn)置transpose、T和swapaxes的實(shí)例講解
下面小編就為大家分享一篇Numpy中轉(zhuǎn)置transpose、T和swapaxes的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
Python3中在Anaconda環(huán)境下安裝basemap包
今天小編就為大家分享一篇關(guān)于Python3中在Anaconda環(huán)境下安裝basemap包的文章,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10

