Warum benötigt man virtuelle Umgebungen?
Gehen wir von folgendem Szenario aus: Man hat zwei Projekte: ProjektA und ProjektB, die beide von der gleichen Bibliothek, ProjektC, abhängig sind. Das Problem wird deutlich, wenn wir anfangen, unterschiedliche Versionen von ProjectC zu benötigen.
Vielleicht benötigt ProjectA die Version v1.0.0, während ProjectB die neuere Version v2.0.0 benötigt.
Dies ist ein echtes Problem für Python, da es nicht zwischen den Versionen im site-packages Verzeichnis unterscheiden kann. Sowohl v1.0.0 als auch v2.0.0 würden sich also im selben Verzeichnis mit demselben Namen befinden.
Da Projekte nur nach ihrem Namen gespeichert werden, gibt es keine Unterscheidung zwischen Versionen. Somit müssten beide Projekte, ProjektA und ProjektB, die gleiche Version verwenden, was in vielen Fällen nicht akzeptabel ist.
An dieser Stelle kommen virtuelle Umgebungen und das Werkzeug venv ins Spiel.
Was ist eine virtuelle Umgebung?
Der Hauptzweck von virtuellen Python-Umgebungen besteht darin, eine isolierte Umgebung für Python-Projekte zu schaffen. Das bedeutet, dass jedes Projekt seine eigenen Abhängigkeiten haben kann, unabhängig davon, welche Abhängigkeiten jedes andere Projekt hat.
In unserem kleinen Beispiel oben müssten wir nur eine separate virtuelle Umgebung für ProjektA und ProjektB erstellen, und wir wären startklar. Jede Umgebung könnte dann unabhängig von der anderen von einer beliebigen Version von ProjektC abhängen.
Das Gute daran ist, dass der Anzahl der Umgebungen keine Grenzen gesetzt sind, da es sich nur um Verzeichnisse mit ein paar Skripten handelt. Außerdem lassen sie sich leicht mit den Kommandozeilenwerkzeugen virtualenv oder pyenv erstellen.
Verwendung einer virtuellen Umgebung
Wenn man Python ab Version 3.6 verwendet, dann ist auf den meisten Systemen das Modul venv aus der Standardbibliothek bereits installiert.
Im Projekt- bzw. Arbeitsverzeichnis erstellt man dann eine virtuelle Umgebung mit folgendem Befehl:
$ python3 -m venv .venv --copies
Die Umgebung wird hier im Verzeichnis .venv erstellt. Man kann jeden gültigen Verzeichnisnamen verwenden, aber .venv ist der Standardname, der für gewöhnlich verwendet wird.
Durch den Parameter –copies wird die Python-Installation übernommen. Ohne Parameter wird nur ein Link auf die Systeminstallation gesetzt. Ändert man die Version der Systeminstallation, wirkt sich dies auch auf die virtuelle Umgebung aus. Im Regelfall möchte man genau das verhindern, daher sollte man den copies-Parameter verwenden.
Die virtuelle Umgebung ist zu aktivieren, damit sie verwendet wird:
$ source .venv/bin/activate
Danach ändert sich der Prompt, so dass man sicher feststellen kann, ob die Umgebung aktiviert ist oder nicht.
(.venv) $
Möchte man einen aussagekräftigen Prompt, dann kann man einen entsprechenden Parameter bei der Erstellung der virtuellen Umgebung angeben:
$ python3 -m venv .venv --copies --prompt xyz
(xyz) $
Um die Umgebung zu deaktivieren, ruft man den gleichnamigen Befehl auf:
(.venv) $ deactivate
Diese virt. Umgebung enthält nach der Installation und Aktivierung zunächst keine Dritt-Anbieter-Module. Es sind also zunächst die benötigten Module mit pip zu installieren!
Parameter
Option | Beschreibung |
---|---|
--symlink | Es werden symbolische Links auf die aktuelle Python-Installation gesetzt, und keine Dateien kopiert. (Default) |
--copies | Die Dateien der aktuellen Python-Installation werden kopiert. |
--clear | Falls die virtuelle Umgebung bereits existiert, wird sie gelöscht, und dann neu angelegt. |
--upgrade | Upgrade der verwendeten Python-Version. |
--without-pip | Überspringt die pip-Installation, wenn eine neue Umgebung erstellt wird. |
--prompt | Individueller Prompt für die virtuelle Umgebung. |
--upgrade-deps | Update der Kern-Abhängigkeiten |
Sonderfall Windows
Die Pfade und Befehle weichen ein wenig ab unter Windows. Unter dem Betriebssystem geht man folgendermaßen vor:
Die virtuelle Umgebung im gewünschten Verzeichnis anlegen (hier z.B. test):
C:>python -m venv c:\test\.venv
Ins Verzeichnis wechseln, und die virtuelle Umgebung aktivieren:
C:\test>.venv\Scripts\activate
.bat (Eingabeaufforderung)C:\test>.venv\Scripts\Activate
.ps1 (Powershell)
Nach Beendigung der Arbeit die virtuelle Umgebung deaktivieren:
C:\test>deactivate
Wie funktioniert eine virtuelle Umgebung?
Zu wissen, was unter der Haube vor sich geht, kann für einen Entwickler wichtig sein, insbesondere wenn man Ausführungsumgebungen oder die Auflösung von Abhängigkeiten verstehen muss.
Um zu verstehen, was das „aktivieren“ bewirkt, sehen wir uns zunächst die Speicherorte der verschiedenen ausführbaren Python-Programme an. Zunächst führen wir bei „deaktivierter“ Umgebung Folgendes aus:
$ which python
/usr/bin/python
Jetzt aktivieren wir die Umgebung, und rufen das Kommando erneut auf:
$ source env/bin/activate
(env) $ which python
/Users/thomas/python-projekt/env/bin/python
Nach der Aktivierung der Umgebung erhalten wir nun einen anderen Pfad für die ausführbare Python-Datei, da in einer aktiven Umgebung die Umgebungsvariable $PATH leicht verändert ist.
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:
$ source env/bin/activate
(env) $ echo $PATH
/Users/thomas/python-projekt/env/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:
Es gibt eigentlich keinen Unterschied zwischen diesen beiden ausführbaren Python-Programmen. Es sind die Verzeichnisse, in denen sie sich befinden.
Wenn Python gestartet wird, schaut es sich den Pfad seiner Binärdatei an. In einer virtuellen Umgebung ist es eigentlich nur eine Kopie oder ein Symlink zur Python-Binärdatei des Systems. Es legt dann die Position von sys.prefix und sys.exec_prefix auf der Grundlage dieser Position fest und lässt den bin-Teil des Pfades weg.
Der Pfad in sys.prefix wird dann zum Auffinden des Site-Packages-Verzeichnisses verwendet, indem der relative Pfad lib/pythonX.X/site-packages/ durchsucht wird, wobei X.X die verwendete Python-Version ist.
In unserem Beispiel befindet sich die Binärdatei unter /Users/thomas/python-projekt/env/bin, was bedeutet, dass sys.prefix /Users/thomas/python-projekt/env ist und das Verzeichnis für die Site-Packages daher /Users/thomas/python-projekt/env/lib/pythonX.X/site-packages ist. Schließlich wird dieser Pfad im Array sys.path gespeichert, das alle Orte enthält, an denen sich ein Paket befinden kann.
Das bedeutet also, sobald eine virtuelle Umgebung aktiviert ist, und mit pip ein Modul installiert wird, wird es unter site-packages der virtuellen. Umgebung gespeichert, und nicht zentral im Systemordner. Damit kann in jeder virt. Umgebung eine andere Version eines bestimmten Moduls vorhanden sein.