In diesem Betriag erkläre ich das Erstellen von virtual environments in Python und welche Vorteile diese mit sich bringen.
Anlegen von virtual environments in Python
Eine neue virtuelle Umgebung erstellt man mit Python entweder über virtualenv (für Python 2.x und auch Python3.x) oder über das seit Python3.3 vorhandene venv Modul.
christian@ubuntu:~$ python3 -m pip install --user virtualenv
christian@ubuntu:~$ virtualenv venv2.7 -p python2.7
Running virtualenv with interpreter /usr/bin/python2.7
Already using interpreter /usr/bin/python2.7
New python executable in /home/christian/venv2.7/bin/python2.7
Also creating executable in /home/christian/venv2.7/bin/python
Installing setuptools, pip, wheel...
done.
christian@ubuntu:~$ virtualenv venv
Using base prefix '/usr'
New python executable in /home/christian/venv/bin/python3.6
Also creating executable in /home/christian/venv/bin/python
Installing setuptools, pip, wheel...
done.
christian@ubuntu:~$ python3.8 -m venv my_venv
Aktivieren einer virtuellen Umgebung
Um eine virtuelle Umgebung zu aktivieren, benutzt man den ’source‘ oder ‚.‘ Befehl. Anschließend sieht man in der Console auch den in Klammern eingefassten Namen der aktiven Umgebung, wie z.B. (venv2.7).
‚deactivate‘ verlässt die virtuelle Umgebung wieder und man arbeitet anschließend mit der systemweit installierten Python Umgebung weiter.
christian@ubuntu:~$ source venv2.7/bin/activate
(venv2.7) christian@ubuntu:~$ python
Python 2.7.17 (default, Jul 20 2020, 15:37:01)
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
(venv2.7) christian@ubuntu:~$ deactivate
christian@ubuntu:~$
christian@ubuntu:~$ . venv/bin/activate
(venv) christian@ubuntu:~$ python
Python 3.6.9 (default, Jul 17 2020, 12:50:27)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Warum eine virtuelle Umgebung benutzt werden sollte
Eine virtuelle Umgebung zu erstellen, vereinfacht viele Dinge. Zum einen ist es möglich eine Umgebung für jede Python Version zu erstellen. Den Code testet man dann jeweils mit dem Interpreter dieser Umgebungen. Auch kann man verschiedene Umgebungen benutzen um unterschiedliche Python Bibliotheken zu installieren und das Zusammenspiel zu prüfen.
christian@ubuntu:~$ . venv2.7/bin/activate
(venv2.7) christian@ubuntu:~$ pip install PyYAML
DEPRECATION: Python 2.7 reached the end of its life on January 1st, ...
Processing ./.cache/pip/wheels/d1/d5/a0/3c27cdc8b0209c5fc1385afeee936cf8a71e13d885388b4be2/PyYAML-5.3.1-cp27-cp27mu-linux_x86_64.whl
Installing collected packages: PyYAML
Successfully installed PyYAML-5.3.1
(venv2.7) christian@ubuntu:~$ pip freeze
DEPRECATION: Python 2.7 reached the end of its life on January 1st, ...
PyYAML==5.3.1
(venv) christian@ubuntu:~$ pip install PyYAML
Collecting PyYAML
Using cached PyYAML-5.3.1.tar.gz (269 kB)
Building wheels for collected packages: PyYAML
Building wheel for PyYAML (setup.py) ... done
Created wheel for PyYAML: filename=PyYAML-5.3.1-cp36-cp36m-linux_x86_64.whl size=44619 sha256=0f1ed03590c156a3a40a55fd371aeb033da6e9ed24e68240133f1f704dfdd2a3
Stored in directory: /home/christian/.cache/pip/wheels/e5/9d/ad/2ee53cf262cba1ffd8afe1487eef788ea3f260b7e6232a80fc
Successfully built PyYAML
Installing collected packages: PyYAML
Successfully installed PyYAML-5.3.1
(venv) christian@ubuntu:~$ pip freeze
PyYAML==5.3.1
Python Scripte können mit dem Python Interpreter der aktivieren virtuellen Umgebung ausgeführt werden. Dadurch erhält das Script automatisch alle in der virtuellen Umgebung vorhandenen Python Bibliotheken.
Das kleine Test Script:
import yaml
def main():
print("imported pyyaml")
if __name__ == "__main__":
main()
wird einmal mit dem Interpreter von Umgebung A (PyYAML installiert) und Umgebung C (ohne PyYAML) ausgeführt:
christian@ubuntu:~/PycharmProjects/einfachpython/src/einfachpython$ source ~/ProjectA/venv_A/bin/activate
(venv_A) christian@ubuntu:~/PycharmProjects/einfachpython/src/einfachpython$ python script_with_pyyaml.py
imported pyyaml
(venv_A) christian@ubuntu:~/PycharmProjects/einfachpython/src/einfachpython$ deactivate
christian@ubuntu:~/PycharmProjects/einfachpython/src/einfachpython$ source ~/ProjectC/venv_C/bin/activate
(venv_C) christian@ubuntu:~/PycharmProjects/einfachpython/src/einfachpython$ python script_with_pyyaml.py
Traceback (most recent call last):
File "script_with_pyyaml.py", line 1, in <module>
import yaml
ModuleNotFoundError: No module named 'yaml'
(venv_C) christian@ubuntu:~/PycharmProjects/einfachpython/src/einfachpython$
Beispiel von virtuellen Umgebungen in unterschiedlichen Projekten
Am wichtigsten ist jedoch, dass für jedes Projekt, welches man bearbeitet, eine eigene virtuelle Umgebung existiert. Für Projekt A installiert man nun Bibliothek PyYAML in Version 5.1, in Projekt B installiert man jedoch andere Bibliotheken. Vielleicht ergibt es sich dann, dass auch Projekt B die PyYAML Bibliothek benötigt, jedoch in einer neueren Version 5.3.1. Also wird nun gefahrlos PyYAML in die Umgebung von Projekt B installiert. Die Umgebung von Projek A bleibt davon unberührt und benutzt weiterhin Bibliothek PyYAML 5.1
Auf diesem Weg vermeidet man also Abhängigkeiten zwischen Projekten. Wäre z.B. alles in der systemweiten Umgebung installiert, müsste man je nach Projekt, das gerade bearbeitet wird, PyYAML up- oder downgraden, um die erforderliche Version zu benutzen.
christian@ubuntu:~$ mkdir ProjectA
christian@ubuntu:~$ cd ProjectA/
christian@ubuntu:~/ProjectA$ python3.8 -m venv venv_A
christian@ubuntu:~/ProjectA$ . venv_A/bin/activate
(venv_A) christian@ubuntu:~/ProjectA$ pip install PyYAML==5.1
Successfully installed PyYAML-5.1
(venv_A) christian@ubuntu:~/ProjectA$ pip freeze
PyYAML==5.1
(venv_A) christian@ubuntu:~/ProjectA$ deactivate
christian@ubuntu:~/ProjectA$ cd ..
christian@ubuntu:~$ mkdir ProjectB
christian@ubuntu:~$ cd ProjectB
christian@ubuntu:~/ProjectB$ python3.8 -m venv venv_B
christian@ubuntu:~/ProjectB$ . venv_B/bin/activate
(venv_B) christian@ubuntu:~/ProjectB$ pip install PyYAML
Successfully installed PyYAML-5.3.1
(venv_B) christian@ubuntu:~/ProjectB$ pip freeze
PyYAML==5.3.1
(venv_B) christian@ubuntu:~/ProjectB$
(venv_B) christian@ubuntu:~/ProjectB$ deactivate
christian@ubuntu:~/ProjectB$ cd ..
christian@ubuntu:~$ . ProjectA/venv_A/bin/activate
(venv_A) christian@ubuntu:~$ pip freeze
PyYAML==5.1
Bibliotheken festlegen und automatisch mit pip installieren
Um für ein Projekt eine für alle Entwickler gleiche Arbeitsumgebung schaffen zu können, benutzt man eine Datei, in der die Bibliotheken definiert sind. Solche requirements Dateien übergibt man mit dem -r Parameter dem install Kommando. Pip installiert dann die dort enhaltenen Pakete selbständig.
Für unser Projekt A erstellen wir uns also eine requirements.txt und legen dort fest, dass wir PyYAML in Version 5.1 benötigen. Ähnlich gehen wir für Projekt B vor, installieren dort aber die aktuellste Version von PyYAML (geben also keine feste Version an).
christian@ubuntu:~$ . ProjectA/venv_A/bin/activate
(venv_A) christian@ubuntu:~$ cat ProjectA/requirements.txt
PyYAML==5.1
(venv_A) christian@ubuntu:~$ pip install -r ProjectA/requirements.txt
Successfully installed PyYAML-5.1
(venv_A) christian@ubuntu:~$ pip freeze
PyYAML==5.1
(venv_A) christian@ubuntu:~$ deactivate
christian@ubuntu:~$ . ProjectB/venv_B/bin/activate
(venv_B) christian@ubuntu:~$ cat ProjectB/requirements.txt
PyYAML
(venv_B) christian@ubuntu:~$ pip install -r ProjectB/requirements.txt
Successfully installed PyYAML-5.3.1
(venv_B) christian@ubuntu:~$ pip freeze
PyYAML==5.3.1
Löschen einer virtuellen Umgebung
Eine virtuelle Umgebung entfernt man einfach durch das Löschen des entsprechenden Verzeichnisses. Vorher deaktiviert man besser die Umgebung.
(venv_A) christian@ubuntu:~$ deactivate
christian@ubuntu:~$ rm -rf ProjectA/venv_A/
Weiterführende Lösungen zum Management von Bibliotheken
Neben dem eher manuellen pip/virtualenv gibt es weitere Lösungen virtuelle Umgebungen zu verwalten. Auch mit pipenv oder conda (im wissenschaftlichen Bereich) erstellt man virtuelle Umgebungen.
tl;dr
Virtuelle Umgebungen erzeugt man mit Python pip (und virtualenv für Py2) und separiert so die Interpreter für unterschiedliche Projekte. Bibliotheken verwaltet man damit für jedes Projekt unabhängig voneinander.
https://github.com/Sprungwunder/einfachpython/blob/master/src/einfachpython/virtualenv_example
Weiterführende Links (in englisch)
https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/