Package Management und Versionskontrolle mit githubInhaltIm neunten Kapitel behandeln wir Package Management, sowie Versionverwaltung und decken die folgenden Konzepte ab:
Package ManagementIn Kapitel 8 haben wir mit numpy, pandas, matplotlib und networkx bereits vier Packages kennen gelernt, die nicht zum Kern von Python gehören. In Kapitel 5 haben wir gelernt, das nach Modulen und Packages im Python Modulpfad gesucht wird. Um diese Packages benutzen können, muss man also dafür sorgen, dass diese im Python Modulpfad verfügbar sind. Hierzu könnte man die Dateien der Packages zum Beispiel als Archiv runterladen und händisch in einen der Ordner des Modulpfads entpacken. Das ist jedoch kompliziert und fehleranfällig, insbesondere wenn man die Version eines Packages ändern möchte, also ein Ugrade auf eine neuere, oder Downgrade auf eine ältere Version, durchführen will. Daher macht man dies in der Regel nicht selbst, sondern benutzt ein Werkzeug für das Package Management. In der Python Welt gibt es hierfür pip. Mit conda gibt es noch eine Alternative zu pip, die wir hier aber nicht näher betrachten. 1. Der Python Package IndexDie Grundlage für das Package Management ist ein Index, auf dem Packages publiziert werden. Der größte und wichtigste Index für Python ist PyPI. Hier findet man nahezu alles, was in Python an Packages öffentlich verfügbar ist. Die Packages liegen hier nicht nur in der neuesten Version vor, sondern auch in allen vorher publizierten Versionen. Daher kann man hier auch einfach alte Versionen beziehen, wenn man diese zum Beispiel aus Kompatibilitätsgründen benötigt. 2. Installieren von Packages mit pippip ist ein Python Package welches man einfach als Kommandozeilenwerkzeug betrachten kann. Das Installieren von Packages mit pip ist sehr einfach und ähnlich zum Arbeiten mit apt unter Ubuntu Linux. Die neuste Version installiert man einfach mit pip install: Kommandozeile mit pip
# Um die neuste Version zu installieren deameni@ndole-dell:~$ pip install # Beispiel von numpy deameni@ndole-dell:~$ pip install numpy # Will man eine bestimmte Version, kann man diese angeben: deameni@ndole-dell:~$ pip install numpy==15.04 # Man kann auch eine mindest Version fordern: deameni@ndole-dell:~$ pip install numpy>=16.00 # Um ein bereits installiertes Package auf eine neuere Version zu upgraden: deameni@ndole-dell:~$ pip install --upgrade numpy # Um mehrere Packages auf einmal zu installieren deameni@ndole-dell:~$ pip install numpy pandas matplotlib networkx Hat man keine Administrationsrechte, kann man häufig Packages nicht global für alle Nutzer eines Betriebssystems installieren. Daher bietet pip mit dem --user Parameter auch die Möglichkeit, Packages nur für einen aktuellen Benutzer zu installieren: pip install –user numpy 3. Datei requirements.txtWill man für ein Projekt angeben, welche Packages benötigt werden, kann man diese in einer Textdatei mit dem Namen requirements.txt definieren. requirements.txt ================ numpy>=16.00 pandas matplotlib networkx Man kann alle Packages dann mit einem Befehl installieren: Ausführung vom Programm
deameni@ndole-dell:~$ pip install -r requirements.txt 4. Installieren von anderen QuellenIst ein Package nicht in PyPI verfügbar, aber zum Beispiel in einem lokalen Ordner oder auf GitHub, kann man dies auch mit pip installieren: Ausführung vom Programm
deameni@ndole-dell:~$ pip install /path/to/local/folder deameni@ndole-dell:~$ pip install ./downloads/archive-1.0.0.tar.gz 5. Eigene Packages mit pip kompatibel machenUm ein Package mit pip installierbar zu machen, bzw. auf PyPI zu veröffentlichen, benötigt man noch einige zusätzliche Dateien.
Die wichtigste dieser Dateien ist die setup.py. Unten ist ein Beispiel von diesem Datei.
Wie man sieht, benutzt die setup.py das Package setuptools. Diese Package stellt die Funktionalität zur Packageerstellung zur Verfügung. Neben dem einfachen Setup aus unserem Beispiel, kann man über die setup.py auch Abhängigkeiten verwalten. Neben den setuptools benötigt man auch noch das Package wheel um ein eigenes Package zu erstellen. Ein Wheel ist das Binärformat für Python Packages. Beides kann man einfach mit pip installieren. Um das Archiv zu erstellen muss man die setup.py mit dem Interpreter ausführen: deameni@ndole-dell:~$ python3 setup.py sdist bdist_wheel Das Package wird dann im Unterordner dist erstellt. Durch den Parameter sdist wird ein .tar.gz Archiv mit den Dateien des Packages erstellt. Durch den Parameter bdist_wheel eine .whl mit dem gebauten +Wheel_ des Packages. Die auf diese Art erstellten Packages kann man jetzt, wenn man entsprechende Accounts hat, auf PyPI, bzw. Test PyPI (Testversion von PyPI auf der man neue Packages testen sollte, bevor man sie bei PyPI hochlädt), hochladen und teilen. Versionskontrolle mit GitWerkzeuge zur Versionskontrolle von Dateien, insbesondere Quelltext, sind ein zentraler Bestandteil der Softwareenticklung. Mit solchen Werkzeugen lassen sich verschiedene Versionen von Dateien verwalten um ihre Änderungshistorie zu verfolgen. Außerdem ermöglichen Versionskontrollsysteme das verteilte Arbeiten an Quelltext an verschiedenen Arbeitsplätzen und insbesondere auch durch Teams. An dieser Stelle gibt es keine umfassende Einführung in Versionskontrolle. Stattdessen gibt es nur ein kurze Einführung in die wichtigsten Funktionen des derzeit verbreitetsten Werkzeugs: git. 1. Git RepositoriesDie Grundlage von git sind die Repositories, vereinfacht gesagt Ordner, für die verschiedene Versionen verwaltet werden. Man kann aus einem normalen Ordner ein git Repository machen, in dem man git init ausführt. Hier sollte man jetzt keine Änderungen mehr durchführen. Stattdessen sollte man eine Arbeitskopie erstellen, in dem man den git clone pathto/repository Befehl benutzt. Die Arbeitskopie ist eine Vollständige Kopie des Hauptrepositories und könnte diese theoretisch komplett ersetzen. In der Praxis legt man eher selten lokal ein git Hauptrepository an. Stattdessen werden diese auf einem Server verwaltet, zum Beispiel bei GitHub oder auch dem GitLab der GWDG. Von dort klont man dann die lokale Kopie. 2. Add, Commit, PushHat man eine Arbeitskopie eines Repositories, kann man in diesem Ordner ganz normal Arbeiten, wie in jedem anderen auch. Die Änderungen werden noch nicht von git mitverfolgt und versioniert. Ist man an einem Punkt, wo man eine neue Version von einer oder mehrerer Datei erstellen will, muss man dies git aktiv mitteilen. Hierzu muss man zuerst mit git add pathtodocument die geänderten Dateien zum Index hinzufügen. Der Index verwaltet Änderungen, die in der Arbeitskopie gemacht wurden. Will man die Änderungen zum Repository hinzufügen, also den aktuellen Index, muss man sie Commiten durch den git commit Befehl. Hierdurch wird eine neue Revision/ des Repositories erstellt, in der die Änderungen des Index beinhaltet sind. Ein Commit wird in der Regel mit einem Kommentar beschrieben, der die Änderungen zusammenfasst. Die Änderungen sind jetzt aber immernoch nur lokal in der Arbeitskopie verfügbar. Will man die Änderungen von der lokalen Arbeitskopie ins Hauptrepository übertragen, muss man diese dort hinpushen. Mit dem Befehl git push wird im Normalfall der aktuelle Branch an origin geschickt. Mit origin wird der Ort bezeichnet, von dem man das mit Hilfe von git clone die Arbeitskopie erstellt hat. Arbeitet man auf dem Hauptentwicklungszweig, sind daher in der Regel folgenden beiden Befehle identisch und übertragen die Änderungen an das Hauptrepository: add, commit and push from einem Datei
>>> git add sqrt.py >>> git commit -m "added new function for calculating the square root" >>> git push origin master # or git push 3. PullZum verteilten Arbeiten gehört auch, dass man Änderungen lokal übernehmen kann, die an einer anderen Stelle gemacht wurden. Oder anders ausgedrückt: Wenn eine Änderung per push ins Hauptrepository übertragen wurde, möchten Sie andere eventuell auch lokal übernehmen, ohne das die eigenen Änderungen verloren gehen oder man das Repository neu klonen muss. Mit git pull kann man Änderungen aus dem Hauptrepository in die Arbeitskopie übernehmen. Gibt es bereits Änderungen in der lokalen Arbeitskopie, wird durch git pull ein sogenannter Merge Commit erstellt. Dieser Commit führt die lokalen Änderungen, mit denen aus dem Hauptrepository wieder zusammen. Ein git pull funktioniert nur dann Reibungslos, wenn es keinen Konflikt zwischen der Arbeitskopie und dem Hauptrepository gibt. Ein Konflikt ensteht dann, wenn der gleiche Bereich in einer Datei geändert wurde, also überlappende Zeilen. Solange nur unterschiedliche Dateien oder zumindest nicht der gleiche Bereich in der selben Datei geändert wurde, gibt es keinen Konflikt. Im Falle eine Konfliktes, gibt es zwei Optionen: Man kann den Merge Commit rückgängig machen, dann hat man jedoch die Änderungen aus dem Hauptrepository nicht in der lokalen Arbeitskopie. Oder man kann den Konflikt lösen. Hierzu zeigt einem git alle Textstellen in Dateien, wo es Konflikte gibt an und man muss selbst entscheiden, welche Variante behalten wird. Details zur Konfliktlösung findet man in der git Dokumentation. 4. Änderungen rückgängig machenEin Vorteil von Versionkontrolle ist, dass man lokale Änderungen auch wieder rückgängig machen kann. Hierzu kann man den Befehl git checkout – benutzen. Mit git checkout kann man im Allgemeinen die Arbeitskopie auf einen bestimmten Commit setzen. Das rückgängig machen von Änderungen ist ein Spezialfall davon. Mit dem folgenden Befehl würde man zum Beispiel die Änderungen an den Dateien sqrt.py und __init__.py rückgängig machen. revisions back
>>> git checkout -- sqrt.py __init__.py
5. Weitere FunktionenOben sind nur die wichtigsten Funktionen erklärt, die man kennen muss um mit git arbeiten zu können. Es gibt jedoch noch weitere wichtige Funktionen, die hier zwar nicht zwingend benötigt werden, aber für den Praxiseinsatz von git in größeren Projekten nicht wegzudenken sind:
|