Daten & KI-Schulungsleitfaden 2021
Laden Sie die GoDataDriven-Broschüre herunter, um einen vollständigen Überblick über die verfügbaren Schulungssitzungen und die Lernreisen für Data Engineering, Data Science, Datenanalysten und Analytiker zu erhalten.
Wenn Sie Python professionell einsetzen, zahlt es sich aus, Ihre Projekte
auf einheitliche Weise einzurichten. Das hilft Ihren Mitarbeitern, die
Struktur eines Projekts schnell zu verstehen, und macht es ihnen leichter, das Projekt
auf ihrem Rechner einzurichten. Der Schlüssel zum Einrichten Ihres Projekts ist die setup.py
Datei.
In diesem Blog werde ich auf die Details dieser Datei eingehen.
Wo wir anfangen
Hier nehme ich an, dass Sie bereits ein Paket haben, das Sie einrichten wollen.
Dies muss kein fertiges Paket sein – idealerweise sollten Sie diesetup.py
erstellen, lange bevor Ihr Projekt fertig ist. Es kann sogar ein leeres Paket sein;
stell nur sicher, dass der Paketordner existiert
und eine Datei namens init.py
enthält (die leer sein kann).
Wenn Sie der Struktur
meines Kollegen Henk für Ihr Projekt folgen, sollte Ihre Ausgangssituation etwa so aussehen:
example_project/├── exampleproject/ Python package with source code.│ ├── __init__.py Make the folder a package.│ └── example.py Example module.└── README.md README with info of the project.
Sie können andere Dateien oder Ordner in Ihrer Struktur haben, zum Beispiel
Ordner namens notebooks/
, tests/
oder data/
, aber diese sind nicht erforderlich.
Der Fall für ein setup.py
Wenn du ein Paket wie dieses erstellt hast, wirst du wahrscheinlich
einen Teil des Codes an anderen Stellen verwenden. Du könntest zum Beispiel
das in einem Notebook machen:
from exampleproject.example import example_function
Das würde funktionieren, wenn dein aktuelles Arbeitsverzeichnis example_project/
ist, aber in
allen anderen Fällen wird Python dir eine Ausgabe wie diese geben:
ModuleNotFoundError: No module named 'exampleproject'
Du könntest Python sagen, wo es nach dem Paket suchen soll, indem du die PYTHONPATH
Umgebungsvariable setzt oder den Pfad zu sys.path
hinzufügst,
aber das ist alles andere als ideal: Es würde verschiedene Aktionen auf verschiedenen
Plattformen erfordern, und der Pfad, den du setzen musst, hängt vom Ort deines Codes ab.
Ein viel besserer Weg ist es, dein Paket mit einer setup.py
und pip
zu installieren,
weil pip
der Standardweg ist, um alle anderen Pakete zu installieren, und es ist verpflichtet
auf allen Plattformen gleich zu funktionieren.
Ein minimales Beispiel
Wie sieht also eine setup.py
Datei aus? Hier ist ein minimales Beispiel0:
from setuptools import setup, find_packagessetup( name='example', version='0.1.0', packages=find_packages(include=))
Hier geben wir drei Dinge an:
- Der Name des Pakets, das ist der Name, den
pip
Ihr Paket verwenden wird.
Dies muss nicht derselbe sein wie der Name des Ordners, in dem das Paket liegt
, obwohl es verwirrend sein kann, wenn es nicht so ist. Ein Beispiel, bei dem der Paket
name und das Verzeichnis nicht übereinstimmen, ist Scikit-Learn: Sie installieren es
unter Verwendung vonpip install scikit-learn
, während Sie es durch Importieren vonsklearn
verwenden. - Die Version Ihres Pakets. Dies ist die Version, die
pip
melden wird, und wird
z.B. verwendet, wenn du dein Paket auf PyPI1 veröffentlichst. - Welche Pakete eingeschlossen werden sollen; in unserem Fall ist dies nur
exampleproject/
.
Hier lassen wirsetuptools
dies automatisch herausfinden
2. Während man im Prinzipfind_packages()
ohne Argumente verwenden könnte, kann dies möglicherweise dazu führen, dass unerwünschte Pakete eingeschlossen werden
. Dies kann zum Beispiel passieren,
wenn Sie ein__init__.py
in Ihrtests/
Verzeichnis aufnehmen. Alternativ können Sie auch dasexclude
Argument verwenden, um explizit
die Aufnahme von Tests in das Paket zu verhindern, aber dies ist etwas
weniger robust.
Alles, was Sie nun tun müssen, um Ihr Paket zu installieren, ist, das Folgende
aus dem example_project/
Verzeichnis3 auszuführen:
pip install -e .
Das .
bezieht sich hier auf das aktuelle Arbeitsverzeichnis, von dem ich annehme, dass es das Verzeichnis
ist, in dem sich das setup.py
befindet. Die -e
Flagge gibt an, dass wir
im editierbaren Modus installieren wollen, was bedeutet,
dass wir, wenn wir die Dateien in unserem Paket bearbeiten, das
Paket nicht neu installieren müssen, bevor die Änderungen in Kraft treten. Du musst entweder
python neu starten oder das Paket neu laden!
Wenn du Informationen im setup.py
selbst editierst, musst du das Paket in den meisten Fällen neu installieren
und auch wenn du neue (Unter-)Pakete hinzufügst.
Im Zweifelsfall kann es nie schaden, neu zu installieren. Führen Sie einfach pip install -e .
erneut aus.
Anforderungen
Die meisten Projekte haben einige Abhängigkeiten. Sie haben höchstwahrscheinlich schon einmal eine
Anforderungen.txt
Datei verwendet, oder eine
Umgebung.yml
, wenn Sie conda
verwenden. Nun, da Sie eine setup.py
erstellen, können Sie Ihre
Abhängigkeiten im install_requires
Argument angeben.
Zum Beispiel können Sie für ein typisches Data Science-Projekt Folgendes haben:
setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=)
Sie können Anforderungen ohne eine Version (PyYAML
) angeben, eine Version festlegen (pandas==0.23.3
), eine minimale
Version angeben ('numpy>=1.14.5
) oder einen Bereich von Versionen festlegen (matplotlib>=2.2.0,<3.0.0
). Diese
Anforderungen werden automatisch von pip
installiert, wenn Sie Ihr Paket installieren.
Extras-require
Manchmal gibt es Abhängigkeiten, die nur in bestimmten Situationen erforderlich sind. Als Datenwissenschaftler
erstelle ich oft Pakete, die ich zum Trainieren eines Modells verwende. Wenn ich an einem solchen Modell interaktiv arbeite
, kann es sein, dass ich matplotlib
und jupyter
installiert haben muss, um interaktiv mit den
Daten zu arbeiten und um Visualisierungen
der Leistung des Modells zu erstellen. Andererseits möchte ich, wenn das Modell in der Produktion läuft, weder matplotlib
noch jupyter
auf dem Rechner (oder Container) installieren, auf dem ich trainiere
oder Inferenzen durchführe. Glücklicherweise erlaubt setuptools
die Angabe von optionalen Abhängigkeiten in extras_require
:
setup( name='example', version='0.1.0', packages=find_packages(include=), install_requires=, extras_require={ 'interactive': , })
Wenn wir nun das Paket normal installieren (pip install example
von PyPI oder pip install -e .
lokal)
wird es nur die Abhängigkeiten PyYAML
, pandas
und numpy
installieren. Wenn wir jedoch
angegeben haben, dass wir die optionalen interactive
Abhängigkeiten (pip install example
oder pip install -e .
) haben wollen,
dann werden auch matplotlib
und jupyter
installiert.
Skripte und Einstiegspunkte
Der Hauptanwendungsfall der meisten Python-Pakete, die man von PyPI installiert, ist die Bereitstellung von Funktionalität
, die in anderem Python-Code verwendet werden kann. Mit anderen Worten, man kann import
von diesen Paketen profitieren.
Als Datenwissenschaftler erstelle ich oft Pakete, die nicht dazu gedacht sind, von anderem Python-Code verwendet zu werden, sondern
etwas zu tun, zum Beispiel ein Modell zu trainieren. Als solches habe ich oft ein Python-Skript, das
ich von der Kommandozeile aus ausführen möchte.
Der beste Weg4 , um die Funktionalität deines Pakets auf der Kommandozeile auszuführen, ist, ein
ein entry_point
wie folgt zu definieren:
setup( # ..., entry_points={ 'console_scripts': })
Jetzt kannst du den Befehl my-command
von der Kommandozeile aus verwenden, der wiederum die main
Funktion innerhalb von exampleproject/example.py
ausführt. Vergessen Sie nicht, neu zu installieren – sonst wird der Befehl
nicht registriert.
Tests
Wenn Sie irgendeinen Code schreiben, empfehle ich Ihnen dringend, auch Tests für diesen Code zu schreiben. Für Tests
mit Python schlage ich vor, pytest
zu verwenden. Natürlich willst du pytest
nicht zu deinen Abhängigkeiten
in install_requires
hinzufügen: es wird von den Benutzern deines Pakets nicht benötigt. Damit es
automatisch installiert wird, wenn du Tests ausführst, kannst du folgendes zu deinem setup.py
hinzufügen:
setup( # ..., setup_requires=, tests_require=,)
Zusätzlich musst du eine Datei mit dem Namen setup.cfg
mit folgendem Inhalt erstellen:
test=pytest
Jetzt kannst du einfach python setup.py test
ausführen und setuptools
stellt sicher, dass die notwendigen Abhängigkeiten
installiert sind und pytest
für dich ausgeführt wird! Schauen Sie hier nach, wenn
Sie Argumente bereitstellen oder Konfigurationsoptionen für pytest
einstellen möchten.
Wenn Sie zusätzliche Anforderungen für das Testen haben (z.B. pytest-flask
), können Sie diese zu tests_require
hinzufügen.
Flake8
Persönlich denke ich, dass es eine gute Idee ist, Flake8 auszuführen, um
die Formatierung Ihres Codes zu überprüfen. Genau wie bei pytest
solltest du flake8
nicht zu deninstall_requires
Abhängigkeiten hinzufügen: es muss nicht installiert sein, um dein
Paket zu benutzen. Stattdessen kannst du es zu setup_requires
:
setup( # ..., setup_requires=)
hinzufügen. Jetzt kannst du einfach python setup.py flake8
ausführen. Natürlich kannst du auch die Version
von flake8
(oder jedem anderen Paket) in setup_requires
.
Wenn du einige der Konfigurationsparameter von Flake8 ändern möchtest, kannst du einen Abschnitt zu
deinem setup.cfg
hinzufügen. Zum Beispiel:
max-line-length=120
Paketdaten
Gelegentlich möchten Sie vielleicht einige Nicht-Python-Dateien in Ihr Paket aufnehmen. Diese
können zum Beispiel Schemadateien oder eine kleine Nachschlagetabelle sein. Seien Sie sich bewusst, dass solche Dateien
zusammen mit Ihrem Code gepackt werden, also ist es im Allgemeinen eine schlechte Idee,
große Dateien einzubinden.
Angenommen, wir haben ein schema.json
in unserem Projekt, das wir in exampleproject/data/schema.json
platzieren.
Wenn wir sie in unser Paket aufnehmen wollen, müssen wir das package_data
-Argument von setup
verwenden:
setup( # ..., package_data={'exampleproject': })
Damit wird sichergestellt, dass die Datei in das Paket aufgenommen wird. Wir können auch wählen, ob wir
alle Dateien basierend auf einem Muster einschließen wollen, zum Beispiel:
setup( # ..., package_data={'': })
Dies fügt alle *.json
Dateien in jedes Paket ein, auf das es trifft.
Versuchen Sie jetzt nicht, den Ort der installierten Dateien selbst herauszufinden, dennpkg_resources
hat einige sehr praktische Komfortfunktionen:
-
pkg_resources.resource_stream
gibt dir einen Stream der Datei, ähnlich wie das
Objekt, das du bekommst, wenn duopen()
aufrufst, -
pkg_resources.resource_string
gibt dir den Inhalt der Datei als String, -
pkg_resources.resource_filename
gibt Ihnen den Dateinamen der Datei (und extrahiert
sie in ein temporäres, wenn sie in einem gepackten Paket enthalten ist), wenn die beiden obigen Optionen
nicht Ihren Bedürfnissen entsprechen.
Zum Beispiel könnten wir unser Schema wie folgt einlesen:
from json import loadfrom pkg_resources import resource_streamschema = load(resource_stream('exampleproject', 'data/schema.json'))
Metadaten
Wenn Sie Ihr Paket veröffentlichen wollen, dann wollen Sie wahrscheinlich Ihren
potentiellen Nutzern einige weitere Informationen über Ihr Paket geben, einschließlich einer Beschreibung,
dem Namen des Autors oder Betreuers und der URL zur Homepage des Pakets.
Eine vollständige Liste aller erlaubten Metadaten finden Sie in den setuptools
Dokumenten.
Zusätzlich, wenn du in PyPI veröffentlichen willst, dann möchtest du vielleicht
automatisch den Inhalt deines README.md
in die long_description
laden,
und Klassifizierer bereitstellen, um pip
mehr über dein Paket zu erzählen.
Wrap-up
Dieser Blog sollte ein guter Startpunkt sein, um die meisten deiner Python-Projekte einzurichten.
Wenn du mehr über Python-Packaging lesen willst, schau dir die Docs an. Hier ist ein Beispiel setup.py
, das alle in diesem Blog gezeigten Teile kombiniert:
from setuptools import setup, find_packagessetup( name='example', version='0.1.0', description='Setting up a python package', author='Rogier van der Geer', author_email='[email protected]', url='https://blog.godatadriven.com/setup-py', packages=find_packages(include=), install_requires=, extras_require={'plotting': }, setup_requires=, tests_require=, entry_points={ 'console_scripts': }, package_data={'exampleproject': })
und das dazugehörige setup.cfg
:
test=pytestmax-line-length=120
Verbessern Sie Ihre Python-Kenntnisse, lernen Sie von den Experten!
Bei GoDataDriven bieten wir eine Vielzahl von Python-Kursen an, vom Anfänger bis zum Experten, die von den besten Fachleuten auf diesem Gebiet unterrichtet werden. Machen Sie mit und verbessern Sie Ihre Python-Kenntnisse:
- Python Essentials – Ideal, wenn Sie gerade erst mit Python anfangen.
- Certified Data Science with Python Foundation – Möchten Sie den Schritt von der Datenanalyse und -visualisierung zu echter Datenwissenschaft machen? Dies ist der richtige Kurs.
- Advanced Data Science with Python – Lernen Sie, Ihre Modelle wie ein Profi zu produzieren und Python für maschinelles Lernen zu verwenden.
Fußnoten
0: In diesem Blog habe ich setuptools
verwendet, um mein Beispielprojekt einzurichten. Alternativ
könnte man auch distutils verwenden,
das das Standardwerkzeug für das Paketieren in Python ist, aber ihm fehlen Features
wie die Funktion find_packages()
und entry_points
.
Da die Verwendung von setuptools heutzutage sehr verbreitet ist und viele seiner Funktionen
besonders nützlich sein können, schlage ich vor, dass du setuptools verwendest.
1: Wenn du möchtest, dass die Version deines Pakets auch innerhalb von Python verfügbar ist,
habe einen Blick darauf.
2: Du könntest deine Pakete auch manuell auflisten, aber das ist besonders fehleranfällig.
3: Alternativ könntest du python setup.py install
ausführen, aber die Verwendung von pip
hat
viele Vorteile, darunter die automatische Installation von Abhängigkeiten und die
Möglichkeit, dein Paket zu deinstallieren oder zu aktualisieren.
4: Sie könnten auch das Argument scripts
verwenden (siehe zum
Beispiel hier)
aber da dies erfordert, dass Sie ein Python-Shell-Skript erstellen, könnte es nicht
so gut (oder überhaupt) unter Windows funktionieren.