Installieren Sie zwei Python-Projekte auf derselben Maschine, kann das zweite das erste zerstören. Eines braucht requests==2.28, das andere requests==2.32, und pip hat genau ein systemweites site-packages-Verzeichnis, in das es schreibt. Die letzte Installation gewinnt, lautlos. Sie merken es, wenn das andere Projekt Fehler wirft, die nichts mit dem Code zu tun haben, den Sie gerade geändert haben.
Eine virtuelle Umgebung gibt jedem Projekt sein eigenes site-packages. Nichts Globales wird berührt, und zwei Projekte können von inkompatiblen Versionen derselben Bibliothek abhängen, ohne dass eines das andere stört.
Was ist eine virtuelle Python-Umgebung?
Ein venv ist ein Verzeichnis mit drei Dingen: einem Python-Interpreter (unter Linux und macOS ein Symlink auf den des Systems), einer pyvenv.cfg-Datei, die auf diese Basisinstallation zurückverweist, und einem site-packages-Ordner, in den pip install Pakete schreibt. Das Aktivieren stellt das bin-Verzeichnis des venv (Scripts unter Windows) an den Anfang des PATH Ihrer Shell, sodass python und pip auf die Kopien des venv statt auf die des Systems verweisen.
Das ist der gesamte Mechanismus. Es gibt keine Dateisystem-Isolation und keine zweite Kopie von Python. Ein venv ändert nur, wo die Shell zwei Programme findet und von wo Importe aufgelöst werden — deshalb dauert das Anlegen eine Sekunde und das Löschen ist rm -rf .venv. Wenn Sie auch das Betriebssystem und das Dateisystem isolieren müssen, ist das die Aufgabe eines Containers, nicht eines venv.
Wie erstellen und aktivieren Sie ein venv?
Die Standardbibliothek liefert das Modul venv mit, es muss also nichts installiert werden:
| |
.venv ist der konventionelle Name, nach dem uv und die meisten Editoren standardmäßig suchen. Die Aktivierung hängt von Ihrer Shell ab:
| OS / Shell | Befehl |
|---|---|
| Linux / macOS (bash, zsh) | source .venv/bin/activate |
| Windows (cmd.exe) | .venv\Scripts\activate.bat |
| Windows (PowerShell) | .venv\Scripts\Activate.ps1 |
Eine frische Windows-Installation blockiert PowerShell-Skripte, auch das Aktivierungsskript. Erlauben Sie lokal erstellte Skripte einmal pro Benutzer:
| |
Sobald das venv aktiv ist, erhält Ihr Prompt das Präfix (.venv), und which python (unter Windows where python) zeigt auf eine Datei in .venv. Führen Sie deactivate aus, um zurückzuwechseln. Das ist eine Shell-Funktion, die das Aktivierungsskript definiert hat, kein eigenständiges Programm.
Die Aktivierung ist optional. .venv/bin/python script.py und .venv/bin/pip install requests funktionieren auch ohne sie, und genau so rufen CI-Pipelines und Editoren das venv im Hintergrund auf.
Sind mehrere Python-Versionen installiert, verwendet python -m venv das python, das die Shell zuerst findet — oft nicht das gemeinte. Geben Sie die Version an: python3.12 -m venv .venv unter Linux und macOS. Unter Windows nutzen Sie den mit Python mitgelieferten py-Launcher, der eine Version anhand der Nummer wählt, unabhängig vom PATH: py -3.12 -m venv .venv.
Wie installieren Sie Pakete mit pip und requirements.txt?
In einem aktiven venv macht pip install <package> genau das, was Sie erwarten. Für Reproduzierbarkeit müssen Sie zusätzlich festhalten, was installiert wurde:
| |
pip freeze schreibt jedes installierte Paket mit seiner exakten Version, einschließlich der Abhängigkeiten Ihrer Abhängigkeiten. Committen Sie requirements.txt, und jeder, der das Projekt klont, führt aus:
| |
und bekommt genau die Versionen, die Sie hatten. Die Schwachstelle: Die Datei vermischt das, was Sie angefordert haben, mit allem, was pip nebenbei mitgebracht hat. Sechs Monate später müssen Sie die ganze Liste lesen und raten, um “ich brauche Flask” von “Flask brauchte Werkzeug 3.1.3” zu unterscheiden.
pyproject.toml oder requirements.txt: Was ist der Unterschied?
pyproject.toml erfasst nur Ihre direkten Abhängigkeiten, mit Versionsbereichen:
| |
pip install . liest diese Datei und löst den gesamten Abhängigkeitsbaum bei der Installation auf. pip install ".[dev]" fügt die Gruppe dev zusätzlich hinzu. Dieselbe Datei enthält auch die Packaging-Metadaten, falls Sie das Projekt irgendwann veröffentlichen — etwas, für das requirements.txt nie gedacht war.
Was sie nicht tut: exakte Versionen festnageln. flask>=3.0 löst sich zur jeweils neuesten Version am Installationstag auf. Das Pinning ist Aufgabe einer Lock-Datei, und venv + pip liefern keine.
In einem Container-Build ist das die Datei, die Sie vor dem restlichen Quellcode kopieren, damit sich der Abhängigkeits-Layer nur neu baut, wenn sich pyproject.toml ändert. Der Leitfaden zu Dockerfile Best Practices erklärt, warum diese Reihenfolge für den Build-Cache wichtig ist.
Wie nutzen Sie uv statt venv und pip?
uv ist eine einzige Rust-Binärdatei, die die Aufgaben von venv, pip, pip-tools und pyenv abdeckt: uv python install 3.12 lädt Python-Versionen herunter und verwaltet sie wie pyenv, sodass uv venv --python 3.12 funktioniert, selbst wenn diese Version noch nicht auf der Maschine ist. Es ist außerdem schnell genug, dass Sie es merken: Eine Auflösung, für die pip mehrere Sekunden braucht, ist in einem Bruchteil dieser Zeit fertig.
Installieren Sie es einmal (die astral.sh-Dokumentation listet den Befehl für jede Plattform). Danach können Sie es auf zwei Arten nutzen.
Als direkter Ersatz für venv und pip, wenn Sie nur Geschwindigkeit wollen:
| |
uv venv erstellt .venv genauso wie python -m venv .venv, und uv pip install akzeptiert dieselben Argumente wie pip. Das Ergebnis aktivieren Sie wie jedes andere venv.
Im Projektmodus, der Locking hinzufügt:
| |
uv init legt das Grundgerüst eines pyproject.toml an. uv add schreibt die Abhängigkeit dort hinein, löst den gesamten Baum auf und schreibt eine uv.lock-Datei, die jede aufgelöste Version fixiert, auch transitive, mit Hashes. Diese Lock-Datei ist das Stück, das pip nicht liefert. Committen Sie sowohl pyproject.toml als auch uv.lock, und ein Kollege führt aus:
| |
Das erstellt .venv, falls es fehlt, und installiert genau das, was die Lock-Datei sagt — nicht das, was die Versionsbereiche in pyproject.toml an diesem Tag auflösen. uv run script.py führt vor der Ausführung dieselbe Sync-Prüfung durch, sodass Ihre Umgebung nicht unbemerkt von der Lock-Datei abweichen kann.
Wie beheben Sie die häufigsten Fehler bei virtuellen Umgebungen?
error: externally-managed-environment. Sie haben pip install außerhalb eines venv auf Debian 12+, Ubuntu 23.04+, Fedora 38+ oder einer ähnlichen Distribution ausgeführt, und das System-Python hat sich verweigert. PEP 668 hat eine Markierungsdatei eingeführt, die der Paketmanager des Betriebssystems in seiner Python-Installation platziert, um zu verhindern, dass pip Pakete überschreibt, die auch apt oder dnf verwalten. Davor konnte ein versehentliches sudo pip install die eigenen Werkzeuge des Betriebssystems auf mühsam zu debuggende Weise zerstören. Manche ältere Anleitungen raten, --break-system-packages hinzuzufügen. Tun Sie das nicht: Das bringt genau den Schaden zurück, den die Markierung verhindert. Legen Sie ein venv an und installieren Sie dort.
Der Editor nutzt den falschen Interpreter. VS Code, PyCharm und ähnliche Tools übernehmen, worauf python beim Öffnen des Projekts verwiesen hat, und das ist nicht unbedingt Ihr venv. Die Symptome: Importe, die im Terminal funktionieren, werden im Editor als nicht auflösbar angezeigt, oder ein vor fünf Minuten installiertes Paket wird nicht gefunden. Stellen Sie den Interpreter des Editors explizit auf .venv/bin/python (.venv\Scripts\python.exe unter Windows).
Das venv wurde in git committet. Das sind einige hundert Megabyte Binärdateien plus absolute Pfade in pyvenv.cfg und den Aktivierungsskripten, also bricht es, sobald jemand das Repo in einen anderen Pfad oder auf ein anderes Betriebssystem klont. Fügen Sie .venv/ zur .gitignore hinzu. Seit Python 3.13 schreibt venv auch selbst eine .gitignore in die neue Umgebung, die deren Inhalt ignoriert, aber auf älteren Versionen müssen Sie das selbst tun. Committen Sie requirements.txt, oder pyproject.toml mit uv.lock. Diese Dateien bauen die Umgebung überall wieder auf. Das Verzeichnis selbst gehört nie ins Repo.
venv, pyproject.toml oder uv: Was sollten Sie verwenden?
Bleiben Sie bei venv + pip + requirements.txt für ein kleines Projekt mit kurzer Abhängigkeitsliste, bei dem Sie kein zusätzliches Tooling wollen. Wechseln Sie zu pyproject.toml, sobald Sie Dev-only-Abhängigkeiten wie Testrunner und Linter haben, die nicht in Produktion gehören, oder sobald Sie planen, das Projekt zu paketieren.
Fügen Sie uv hinzu, wenn die Auflösungsgeschwindigkeit anfängt zu stören oder Sie eine committete Lock-Datei wollen, ohne eine von Hand mit pip-tools zu pflegen. Es erzwingt keine Neuschreibung: Führen Sie uv init bei einem neuen Projekt aus, oder uv venv und uv pip install -r requirements.txt bei einem bestehenden, und wechseln Sie zu uv add, sobald Sie für die Lock-Datei bereit sind.