En dybdegående sammenligning af setup.py og pyproject.toml til Python pakkehåndtering, der dækker bedste praksis, migrationsstrategier og moderne værktøjer.
Python Pakkestruktur: Setup.py vs. Pyproject.toml - En Omfattende Vejledning
I årevis var setup.py
-filen hjørnestenen i Python pakkehåndtering. Landskabet har dog udviklet sig, og pyproject.toml
er dukket op som et moderne alternativ. Denne omfattende vejledning udforsker forskellene mellem disse to tilgange og hjælper dig med at forstå, hvilken der er rigtig for dit projekt, og hvordan du effektivt administrerer dine Python-pakker.
Forståelse af det Grundlæggende
Hvad er en Python-pakke?
En Python-pakke er en måde at organisere og distribuere din Python-kode på. Den giver dig mulighed for at gruppere relaterede moduler i et mappehierarki, hvilket gør din kode mere modulær, genanvendelig og vedligeholdelsesvenlig. Pakker er essentielle for at dele din kode med andre og for at administrere afhængigheder i dine projekter.
Rollen af Pakke Metadata
Pakke metadata giver essentiel information om din pakke, såsom dens navn, version, forfatter, afhængigheder og entry points. Disse metadata bruges af pakkehåndteringssystemer som pip
til at installere, opgradere og administrere dine pakker. Historisk set var setup.py
den primære måde at definere disse metadata på.
Setup.py: Den Traditionelle Tilgang
Hvad er Setup.py?
setup.py
er et Python-script, der bruger setuptools
-biblioteket til at definere strukturen og metadata for din pakke. Det er en dynamisk eksekveret fil, hvilket betyder, at den kører Python-kode for at konfigurere pakken.
Nøglekomponenter i Setup.py
En typisk setup.py
-fil indeholder følgende komponenter:
- Pakkenavn: Navnet på din pakke (f.eks.
my_package
). - Version: Versionsnummeret på din pakke (f.eks.
1.0.0
). - Information om Forfatter og Vedligeholder: Detaljer om pakkens forfatter og vedligeholder.
- Afhængigheder: En liste over andre pakker, som din pakke afhænger af (f.eks.
requests >= 2.20.0
). - Entry Points: Definitioner for kommandolinjescripts eller andre entry points til din pakke.
- Pakke Data: Ikke-kode-filer (f.eks. konfigurationsfiler, datafiler), der skal inkluderes i pakken.
Eksempel på Setup.py
from setuptools import setup, find_packages
setup(
name='my_package',
version='1.0.0',
author='John Doe',
author_email='john.doe@example.com',
description='A simple Python package',
packages=find_packages(),
install_requires=[
'requests >= 2.20.0',
],
entry_points={
'console_scripts': [
'my_script = my_package.module:main',
],
},
classifiers=[
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
)
Fordele ved Setup.py
- Kendskab: Det er den traditionelle og velkendte tilgang, så mange udviklere er allerede bekendt med den.
- Fleksibilitet: Fordi det er et Python-script, tilbyder det en høj grad af fleksibilitet. Du kan udføre kompleks logik og tilpasse byggeprocessen efter behov.
- Udvidelsesmulighed: Setuptools tilbyder et rigt sæt funktioner og kan udvides med brugerdefinerede kommandoer og udvidelser.
Ulemper ved Setup.py
- Dynamisk Eksekvering: Den dynamiske karakter af
setup.py
kan være en sikkerhedsrisiko, da den eksekverer vilkårlig kode under byggeprocessen. - Underforståede Afhængigheder:
setup.py
er ofte afhængig af underforståede afhængigheder, såsom setuptools selv, hvilket kan føre til uoverensstemmelser og fejl. - Kompleksitet: For komplekse projekter kan
setup.py
blive stor og svær at vedligeholde. - Begrænset Deklarativ Konfiguration: Meget af pakke metadata er defineret imperativt snarere end deklarativt, hvilket gør det sværere at ræsonnere om.
Pyproject.toml: Det Moderne Alternativ
Hvad er Pyproject.toml?
pyproject.toml
er en konfigurationsfil, der bruger TOML-formatet (Tom's Obvious, Minimal Language) til at definere byggesystemet og metadata for din pakke. Det er en deklarativ tilgang, hvilket betyder, at du specificerer, hvad du vil opnå, snarere end hvordan du vil opnå det.
Vigtige Sektioner i Pyproject.toml
En typiskpyproject.toml
-fil indeholder følgende sektioner:
[build-system]
: Definerer det byggesystem, der skal bruges (f.eks.setuptools
,poetry
,flit
).[project]
: Indeholder metadata om projektet, såsom dets navn, version, beskrivelse, forfattere og afhængigheder.[tool.poetry]
eller[tool.flit]
: Sektioner til værktøjsspecifikke konfigurationer (f.eks. Poetry, Flit).
Eksempel på Pyproject.toml (med Setuptools)
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[project]
name = "my_package"
version = "1.0.0"
description = "A simple Python package"
authors = [
{ name = "John Doe", email = "john.doe@example.com" }
]
dependencies = [
"requests >= 2.20.0",
]
[project.scripts]
my_script = "my_package.module:main"
[project.optional-dependencies]
dev = [
"pytest",
"flake8",
]
[project.classifiers]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
[project.urls]
homepage = "https://example.com"
repository = "https://github.com/example/my_package"
Eksempel på Pyproject.toml (med Poetry)
[tool.poetry]
name = "my_package"
version = "1.0.0"
description = "A simple Python package"
authors = ["John Doe "]
license = "MIT"
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.7,<3.12"
requests = ">=2.20.0"
[tool.poetry.dev-dependencies]
pytest = "^6.0"
flake8 = "^3.9"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Fordele ved Pyproject.toml
- Deklarativ Konfiguration:
pyproject.toml
giver en deklarativ måde at definere din pakke metadata på, hvilket gør den nemmere at forstå og vedligeholde. - Standardiseret Byggesystem: Den specificerer det byggesystem, der skal bruges, hvilket sikrer ensartede builds på tværs af forskellige miljøer.
- Forbedret Afhængighedshåndtering: Værktøjer som Poetry og Pipenv integreres problemfrit med
pyproject.toml
for at tilbyde robuste afhængighedshåndteringsfunktioner. - Reduceret Sikkerhedsrisiko: Da det er en statisk konfigurationsfil, eliminerer den sikkerhedsrisici forbundet med dynamisk eksekvering af kode under byggeprocessen.
- Integration med Moderne Værktøjer:
pyproject.toml
er standarden for moderne Python pakkeværktøjer som Poetry, Pipenv og Flit.
Ulemper ved Pyproject.toml
- Indlæringskurve: Udviklere kan blive nødt til at lære en ny syntaks (TOML) og en ny måde at tænke på pakkehåndtering.
- Begrænset Fleksibilitet: Den er muligvis ikke egnet til meget tilpassede byggeprocesser, der kræver kompleks logik.
- Værktøjsafhængighed: Du bliver nødt til at vælge og lære at bruge et specifikt byggesystem (f.eks. Setuptools, Poetry, Flit).
Sammenligning af Setup.py og Pyproject.toml
Her er en tabel, der opsummerer de vigtigste forskelle mellem setup.py
og pyproject.toml
:
Funktion | Setup.py | Pyproject.toml |
---|---|---|
Konfigurationsstil | Imperativ (Python-kode) | Deklarativ (TOML) |
Byggesystem | Underforstået (Setuptools) | Eksplicit (specificeret i [build-system] ) |
Sikkerhed | Potentielt mindre sikker (dynamisk eksekvering) | Mere sikker (statisk konfiguration) |
Afhængighedshåndtering | Grundlæggende (install_requires ) |
Avanceret (integration med Poetry, Pipenv) |
Værktøjer | Traditionel (Setuptools) | Moderne (Poetry, Pipenv, Flit) |
Fleksibilitet | Høj | Moderat |
Kompleksitet | Kan være høj for komplekse projekter | Generelt lavere |
Migrationsstrategier: Fra Setup.py til Pyproject.toml
Migration fra setup.py
til pyproject.toml
kan virke skræmmende, men det er en værdifuld investering for langsigtet vedligeholdelse og ensartethed. Her er et par strategier, du kan bruge:
1. Start med en Minimal Pyproject.toml
Opret en simpel pyproject.toml
-fil, der specificerer byggesystemet, og migrer derefter gradvist metadata fra setup.py
til pyproject.toml
.
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
2. Brug Setuptools med Pyproject.toml
Fortsæt med at bruge Setuptools som dit byggesystem, men definer projektmetadata i pyproject.toml
. Dette giver dig mulighed for at udnytte fordelene ved pyproject.toml
, mens du stadig bruger et velkendt værktøj.
3. Migrer til et Moderne Værktøj som Poetry
Overvej at migrere til et moderne værktøj som Poetry eller Pipenv. Disse værktøjer tilbyder omfattende afhængighedshåndteringsfunktioner og integreres problemfrit med pyproject.toml
.
Eksempel: Migration til Poetry
- Installer Poetry:
pip install poetry
- Initialiser Poetry i dit projekt:
poetry init
(Dette guider dig gennem oprettelsen af enpyproject.toml
-fil) - Tilføj dine afhængigheder:
poetry add requests
(eller andre afhængigheder) - Byg din pakke:
poetry build
4. Brug Værktøjer til Automatiseret Migration
Nogle værktøjer kan hjælpe med at automatisere migrationsprocessen. Du kan for eksempel bruge værktøjer til at konvertere din setup.py
-fil til en pyproject.toml
-fil.
Bedste Praksis for Python Pakkehåndtering
1. Brug et Virtuelt Miljø
Brug altid et virtuelt miljø til at isolere dit projekts afhængigheder fra den systemomfattende Python-installation. Dette forhindrer konflikter og sikrer, at dit projekt har de korrekte afhængigheder.
Eksempel med brug af venv
:
python3 -m venv .venv
source .venv/bin/activate # På Linux/macOS
.venv\Scripts\activate # På Windows
Eksempel med brug af conda
:
conda create -n myenv python=3.9
conda activate myenv
2. Specificer Afhængigheder Nøjagtigt
Brug versionsbegrænsninger til at specificere de kompatible versioner af dine afhængigheder. Dette forhindrer uventet adfærd forårsaget af inkompatible biblioteksopdateringer. Brug værktøjer som pip-tools
til at administrere dine afhængigheder.
Eksempel på afhængighedsspecificering:
requests >= 2.20.0, < 3.0.0
3. Brug et Konsistent Byggesystem
Vælg et byggesystem (f.eks. Setuptools, Poetry, Flit) og hold dig til det. Dette sikrer ensartede builds på tværs af forskellige miljøer og forenkler pakningsprocessen.
4. Dokumenter Din Pakke
Skriv klar og præcis dokumentation for din pakke. Dette hjælper brugere med at forstå, hvordan de bruger din pakke, og gør det nemmere for andre at bidrage til dit projekt. Brug værktøjer som Sphinx til at generere dokumentation fra din kode.
5. Brug Continuous Integration (CI)
Opsæt et CI-system (f.eks. GitHub Actions, Travis CI, GitLab CI) til automatisk at bygge, teste og implementere din pakke, hver gang der foretages ændringer i din kode. Dette hjælper med at sikre, at din pakke altid er i en fungerende tilstand.
Eksempel på GitHub Actions-konfiguration:
name: Python Package
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install
- name: Lint with flake8
run: |
poetry run flake8 .
- name: Test with pytest
run: |
poetry run pytest
6. Udgiv Din Pakke på PyPI
Del din pakke med verden ved at udgive den på Python Package Index (PyPI). Dette gør det nemt for andre at installere og bruge din pakke.
Trin til udgivelse på PyPI:
- Registrer en konto på PyPI og TestPyPI.
- Installer
twine
:pip install twine
. - Byg din pakke:
poetry build
ellerpython setup.py sdist bdist_wheel
. - Upload din pakke til TestPyPI:
twine upload --repository testpypi dist/*
. - Upload din pakke til PyPI:
twine upload dist/*
.
Reelle Eksempler
Lad os se på, hvordan nogle populære Python-projekter bruger pyproject.toml
:
- Poetry: Bruger
pyproject.toml
til sin egen pakkehåndtering. - Black: Den kompromisløse kodeformaterer bruger også
pyproject.toml
. - FastAPI: Et moderne, hurtigt (højtydende) web-framework til opbygning af API'er med Python bruger det også.
Konklusion
pyproject.toml
repræsenterer den moderne standard for Python pakkehåndtering, der tilbyder en deklarativ og sikker måde at definere din pakke metadata og administrere afhængigheder på. Mens setup.py
har tjent os godt, er migration til pyproject.toml
en værdifuld investering for langsigtet vedligeholdelse, ensartethed og integration med moderne værktøjer. Ved at adoptere bedste praksis og bruge de rigtige værktøjer kan du strømline din Python paknings-workflow og skabe højkvalitets, genanvendelige pakker.