Die Einrichtung eines Python-Projekts bedeutete früher, zahlreiche kleine Entscheidungen zu treffen, bevor man die erste nützliche Zeile Code schrieb. Welche Umgebung verwalten? Welches Abhängigkeitswerkzeug verwenden? Welcher Formatter? Welcher Linter? Welcher Typprüfer? Und wenn das Projekt Daten berührte, sollte man dann mit pandas, DuckDB oder etwas Neuem beginnen?
Im Jahr 2026 kann diese Einrichtung erheblich vereinfacht werden.
Für die meisten neuen Projekte stellt der sauberste Standard-Stack Folgendes bereit:
- uv für die Python-Installation, Umgebungsverwaltung, Abhängigkeitsmanagement, Sperrung und Ausführung von Befehlen.
- Ruff für Linting und Formatierung.
- Ty für die Typprüfung.
- Polars für die Arbeit mit DataFrames.
Dieser Stack ist schnell, modern und bemerkenswert kohärent. Drei der vier Werkzeuge (uv, Ruff und Ty) stammen tatsächlich von derselben Firma, Astral, was eine nahtlose Integration untereinander und mit Ihrer pyproject.toml ermöglicht.
Warum dieser Stack funktioniert
Ältere Setups sahen oft so aus:
- pyenv + pip + venv + pip-tools oder Poetry + Black + isort + Flake8 + mypy + pandas
Dies funktionierte, führte jedoch zu erheblichen Überschneidungen, Inkonsistenzen und Wartungsaufwand. Man hatte separate Werkzeuge für die Einrichtung der Umgebung, die Sperrung von Abhängigkeiten, die Formatierung, das Import-Sorting, Linting und Typisierung. Jedes neue Projekt begann mit einer Explosion an Entscheidungen. Der Standard-Stack von 2026 vereinfacht all dies. Das Endergebnis sind weniger Werkzeuge, weniger Konfigurationsdateien und weniger Reibung beim Onboarding von Mitwirkenden oder beim Einrichten von Continuous Integration (CI).
Bevor wir mit der Einrichtung beginnen, werfen wir einen kurzen Blick darauf, was jedes Werkzeug im Stack von 2026 bewirkt:
- uv: Dies ist die Basis Ihrer Projektkonfiguration. Es erstellt das Projekt, verwaltet Versionen, kümmert sich um Abhängigkeiten und führt Ihren Code aus. Anstatt virtuelle Umgebungen manuell einzurichten und Pakete zu installieren, übernimmt uv die schwere Arbeit. Es sorgt dafür, dass Ihre Umgebung konsistent bleibt, indem es eine Sperrdatei verwendet und sicherstellt, dass alles korrekt ist, bevor ein Befehl ausgeführt wird.
- Ruff: Dies ist Ihr All-in-One-Werkzeug für Codequalität. Es ist extrem schnell, überprüft auf Probleme, behebt viele davon automatisch und formatiert auch Ihren Code. Sie können es anstelle von Werkzeugen wie Black, isort, Flake8 und anderen verwenden.
- Ty: Dies ist ein neueres Werkzeug zur Typprüfung. Es hilft, Fehler zu erkennen, indem es die Typen in Ihrem Code überprüft und mit verschiedenen Editoren funktioniert. Obwohl es neuer ist als Werkzeuge wie mypy oder Pyright, ist es für moderne Arbeitsabläufe optimiert.
- Polars: Dies ist eine moderne Bibliothek zur Arbeit mit DataFrames. Sie konzentriert sich auf effiziente Datenverarbeitung durch Lazy Execution, was bedeutet, dass sie Abfragen optimiert, bevor sie ausgeführt werden. Dies macht sie schneller und speichereffizienter als pandas, insbesondere bei großen Datenaufgaben.
Voraussetzungen überprüfen
Die Einrichtung ist recht einfach. Hier sind die wenigen Dinge, die Sie benötigen, um zu beginnen:
- Terminal: macOS Terminal, Windows PowerShell oder eine beliebige Linux-Shell.
- Internetverbindung: Erforderlich für den einmaligen uv-Installer und die Paketdownloads.
- Code-Editor: VS Code wird empfohlen, da er gut mit Ruff und Ty funktioniert, aber jeder Editor ist in Ordnung.
- Git: Erforderlich für die Versionskontrolle; beachten Sie, dass uv automatisch ein Git-Repository initialisiert.
Das war’s. Sie benötigen keine vorinstallierte Python-Version. Sie benötigen kein pip, venv, pyenv oder conda. uv kümmert sich um die Installation und Umgebungsverwaltung für Sie.
Schritt 1: Installation von uv
uv bietet einen eigenständigen Installer, der auf macOS, Linux und Windows funktioniert, ohne dass Python oder Rust auf Ihrem Rechner vorhanden sein müssen.
Für macOS und Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Für Windows PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Nach der Installation starten Sie Ihr Terminal neu und überprüfen:
uv --version
Ausgabe:
uv 0.8.0 (Homebrew 2025-07-17)
Dieses einzelne Binary ersetzt nun pyenv, pip, venv, pip-tools und die Projektmanagement-Schicht von Poetry.
Schritt 2: Erstellen eines neuen Projekts
Wechseln Sie in Ihr Projektverzeichnis und erstellen Sie ein neues:
uv init my-project\ncd my-project
uv erstellt eine saubere Startstruktur:
my-project/\n├── .python-version\n├── pyproject.toml\n├── README.md\n└── main.py
Gestalten Sie es in ein src/-Layout um, was Importe, Verpackung, Testisolierung und Typprüferkonfiguration verbessert:
mkdir -p src/my_project tests data/raw data/processed\nmv main.py src/my_project/main.py\ntouch src/my_project/__init__.py tests/test_main.py
Ihre Struktur sollte nun so aussehen:
my-project/\n├── .python-version\n├── README.md\n├── pyproject.toml\n├── uv.lock\n├── src/\n│ └── my_project/\n│ ├── __init__.py\n│ └── main.py\n├── tests/\n│ └── test_main.py\n└── data/\n ├── raw/\n └── processed/
Wenn Sie eine bestimmte Version benötigen (z. B. 3.12), kann uv diese installieren und festlegen:
uv python install 3.12\nuv python pin 3.12
Der Befehl pin schreibt die Version in .python-version, um sicherzustellen, dass jedes Teammitglied denselben Interpreter verwendet.
Schritt 3: Abhängigkeiten hinzufügen
Das Hinzufügen von Abhängigkeiten erfolgt mit einem einzigen Befehl, der gleichzeitig auflöst, installiert und sperrt:
uv add polars
uv erstellt automatisch eine virtuelle Umgebung (.venv/), falls noch keine existiert, löst den Abhängigkeitsbaum auf, installiert Pakete und aktualisiert uv.lock mit genauen, festgelegten Versionen.
Für Werkzeuge, die nur während der Entwicklung benötigt werden, verwenden Sie das Flag --dev:
uv add --dev ruff ty pytest
Dies platziert sie in einem separaten [dependency-groups]-Abschnitt in pyproject.toml, wodurch die Produktionsabhängigkeiten schlank bleiben. Sie müssen source .venv/bin/activate nie ausführen; wenn Sie uv run verwenden, wird automatisch die richtige Umgebung aktiviert.
Schritt 4: Konfiguration von Ruff (Linting und Formatierung)
Ruff wird direkt in Ihrer pyproject.toml konfiguriert. Fügen Sie die folgenden Abschnitte hinzu:
[tool.ruff]\nline-length = 100\ntarget-version = "py312"\n[tool.ruff.lint]\nselect = ["E4", "E7", "E9", "F", "B", "I", "UP"]\n[tool.ruff.format]\ndocstring-code-format = true\nquote-style = "double"
Eine Zeilenlänge von 100 Zeichen ist ein guter Kompromiss für moderne Bildschirme. Regelgruppen wie flake8-bugbear (B), isort (I) und pyupgrade (UP) fügen echten Wert hinzu, ohne ein neues Repository zu überfordern.
Ruff ausführen:
# Lint your code\nuv run ruff check .\n# Auto-fix issues where possible\nuv run ruff check --fix .\n# Format your code\nuv run ruff format .
Beachten Sie das Muster: uv run <tool> <args>. Sie installieren Werkzeuge nie global oder aktivieren Umgebungen manuell.
Schritt 5: Konfiguration von Ty für die Typprüfung
Ty wird ebenfalls in pyproject.toml konfiguriert. Fügen Sie diese Abschnitte hinzu:
[tool.ty.environment]\nroot = ["./src"]\n[tool.ty.rules]\nall = "warn"\n[[tool.ty.overrides]]\ninclude = ["src/**"]\n[tool.ty.overrides.rules]\npossibly-unresolved-reference = "error"\n[tool.ty.terminal]\nerror-on-warning = false\noutput-format = "full"
Diese Konfiguration startet Ty im Warnmodus, was ideal für die Einführung ist. Zuerst beheben Sie offensichtliche Probleme und fördern dann schrittweise Regeln zu Fehlern. Die Datenverzeichnisse werden ausgeschlossen, um Rauschen durch den Typprüfer aus nicht-code Verzeichnissen zu vermeiden.
Schritt 6: Konfiguration von pytest
Fügen Sie einen Abschnitt für pytest hinzu:
[tool.pytest.ini_options]\ntestpaths = ["tests"]
Führen Sie Ihre Testsuite mit folgendem Befehl aus:
uv run pytest
Schritt 7: Überprüfung der vollständigen pyproject.toml
Hier ist, wie Ihre endgültige Konfiguration aussieht, mit allem verbunden — eine Datei, jedes Werkzeug konfiguriert, ohne verstreute Konfigurationsdateien:
[project]\nname = "my-project"\nversion = "0.1.0"\ndescription = "Modernes Python-Projekt mit uv, Ruff, Ty und Polars"\nreadme = "README.md"\nrequires-python = ">=3.13"\ndependencies = [\n "polars>=1.39.3",\n]\n[dependency-groups]\ndev = [\n "pytest>=9.0.2",\n "ruff>=0.15.8",\n "ty>=0.0.26",\n]\n[tool.ruff]\nline-length = 100\ntarget-version = "py312"\n[tool.ruff.lint]\nselect = ["E4", "E7", "E9", "F", "B", "I", "UP"]\n[tool.ruff.format]\ndocstring-code-format = true\nquote-style = "double"\n[tool.ty.environment]\nroot = ["./src"]\n[tool.ty.rules]\nall = "warn"\n[[tool.ty.overrides]]\ninclude = ["src/**"]\n[tool.ty.overrides.rules]\npossibly-unresolved-reference = "error"\n[tool.ty.terminal]\nerror-on-warning = false\noutput-format = "full"\n[tool.pytest.ini_options]\ntestpaths = ["tests"]
Schritt 8: Code schreiben mit Polars
Ersetzen Sie den Inhalt von src/my_project/main.py durch Code, der die Polars-Seite des Stacks nutzt:
"""Beispiel einer Datenanalyse mit Polars."""\nimport polars as pl\n\ndef build_report(path: str) -> pl.DataFrame:\n """Erstellen Sie eine Umsatzübersicht aus Rohdaten mit der Lazy API."""\n q = (\n pl.scan_csv(path)\n .filter(pl.col("status") == "active")\n .with_columns(\n revenue_per_user=(pl.col("revenue") / pl.col("users")).alias("rpu")\n )\n .group_by("segment")\n .agg(\n pl.len().alias("rows"),\n pl.col("revenue").sum().alias("revenue"),\n pl.col("rpu").mean().alias("avg_rpu"),\n )\n .sort("revenue", descending=True)\n )\n return q.collect()\n\ndef main() -> None:\n """Einstiegspunkt mit Beispiel für In-Memory-Daten."""\n df = pl.DataFrame(\n {\n "segment": ["Enterprise", "SMB", "Enterprise", "SMB", "Enterprise"],\n "status": ["active", "active", "churned", "active", "active"],\n "revenue": [12000, 3500, 8000, 4200, 15000],\n "users": [120, 70, 80, 84, 150],\n }\n )\n summary = (\n df.lazy()\n .filter(pl.col("status") == "active")\n .with_columns(\n (pl.col("revenue") / pl.col("users")).round(2).alias("rpu")\n )\n .group_by("segment")\n .agg(\n pl.len().alias("rows"),\n pl.col("revenue").sum().alias("total_revenue"),\n pl.col("rpu").mean().round(2).alias("avg_rpu"),\n )\n .sort("total_revenue", descending=True)\n .collect()\n )\n print("Umsatzübersicht:")\n print(summary)\n\nif __name__ == "__main__":\n main()
Bevor Sie ausführen, benötigen Sie ein Build-System in pyproject.toml, damit uv Ihr Projekt als Paket installiert. Wir verwenden Hatchling:
cat >> pyproject.toml << 'EOF'\n[build-system]\nrequires = ["hatchling"]\nbuild-backend = "hatchling.build"\n[tool.hatch.build.targets.wheel]\npackages = ["src/my_project"]\nEOF
Synchronisieren und ausführen:
uv sync\nuv run python -m my_project.main
Sie sollten eine formatierte Polars-Tabelle sehen:
Umsatzübersicht:\nshape: (2, 4)\n┌────────────┬──────┬───────────────┬─────────┐\n│ segment ┆ rows ┆ total_revenue ┆ avg_rpu │\n│ --- ┆ --- ┆ --- ┆ --- │\n│ str ┆ u32 ┆ i64 ┆ f64 │\n╞════════════╪══════╪═══════════════╪═════════╡\n│ Enterprise ┆ 2 ┆ 27000 ┆ 100.0 │\n│ SMB ┆ 2 ┆ 7700 ┆ 50.0 │\n└────────────┴──────┴───────────────┴─────────┘
Verwaltung des täglichen Workflows
Nachdem das Projekt eingerichtet ist, ist der tägliche Ablauf unkompliziert:
# Pull latest, sync dependencies\ngit pull\nuv sync\n# Write code...\n# Before committing: lint, format, type-check, test\nuv run ruff check --fix .\nuv run ruff format .\nuv run ty check\nuv run pytest\n# Commit\ngit add .\ngit commit -m "feat: add revenue report module"
Die Art und Weise, wie Sie Python mit Polars schreiben
Der größte Denkansatzwechsel in diesem Stack betrifft die Datenverarbeitung. Mit Polars sollten Ihre Standards sein:
- Ausdrücke statt zeilenweiser Operationen. Polars-Ausdrücke ermöglichen es der Engine, Abfragen zu optimieren, bevor sie ausgeführt werden, was die Effizienz erheblich steigert. Wenn Sie mehr über die Grundlagen der Datenwissenschaft erfahren möchten, werfen Sie einen Blick auf wichtige Skills und Fallstricke.
- Effiziente Merkmalsauswahl ist entscheidend für den Erfolg Ihres Projekts. Nutzen
Bildquelle: ai-generated-gemini