Blog

Eine praktische Anleitung zur Verwendung von Setup.py

Rogier van der Geer

Rogier van der Geer

Aktualisiert Oktober 21, 2025
10 Minuten

Hinweis: Heutzutage wird von der Verwendung von setup.py zugunsten von pyproject.toml zusammen mit setup.cfg abgeraten. Erfahren Sie hier, wie Sie diese verwenden können.

Wenn Sie professionell mit Python arbeiten, lohnt es sich, Ihre Projekte einheitlich einzurichten. Dies hilft Ihren Mitarbeitern, die Struktur eines Projekts schnell zu verstehen, und erleichtert ihnen die Einrichtung des Projekts auf ihrem Rechner. Der Schlüssel zum Einrichten Ihres Projekts ist die Datei setup.py. In diesem Blog werde ich auf die Einzelheiten dieser Datei eingehen.

Wo wir beginnen

Hier gehe ich davon aus, dass Sie bereits ein Paket haben, das Sie einrichten möchten. Dabei muss es sich nicht um ein fertiges Paket handeln - idealerweise sollten Sie das setup.py lange vor der Fertigstellung Ihres Projekts erstellen. Es kann sogar ein leeres Paket sein; stellen Sie 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 in etwa so aussehen:

Beispiel_Projekt/
├── Beispielprojekt/       Python-Paket mit Quellcode.
│ ├── __init__.py  Machen Sie den Ordner zu einem Paket.
│ └── example.py  Beispielmodul.
└── README.md  README mit Informationen zum Projekt.

Sie können auch andere Dateien oder Ordner in Ihrer Struktur haben, zum Beispiel Ordner mit den Namen notebooks/, tests/ oder data/, aber diese sind nicht erforderlich.

Der Fall für eine setup.py

Wenn Sie ein solches Paket erstellt haben, werden Sie wahrscheinlich einen Teil des Codes an anderen Stellen verwenden. Zum Beispiel könnten Sie in einem Notizbuch verwenden wollen:

von beispielprojekt.beispiel importieren beispiel_funktion

Dies würde funktionieren, wenn Ihr aktuelles Arbeitsverzeichnis example_project/ ist, aber in allen anderen Fällen gibt Python eine Ausgabe wie diese:

ModuleNotFoundError: Nein Modul namens 'Beispielprojekt'

Sie könnten Python mitteilen, wo es nach dem Paket suchen soll, indem Sie die Umgebungsvariable PYTHONPATH setzen oder den Pfad zu sys.path hinzufügen, aber das ist alles andere als ideal: Es würde auf verschiedenen Plattformen unterschiedliche Aktionen erfordern, und der Pfad, den Sie setzen müssen, hängt vom Ort Ihres Codes ab. Ein viel besserer Weg ist es, Ihr Paket mit setup.py und pip zu installieren, denn pip ist der Standardweg, um alle anderen Pakete zu installieren, und er funktioniert zwangsläufig auf allen Plattformen gleich.

Ein minimales Beispiel

Wie sieht also eine setup.py Datei aus? Hier ist ein minimales Beispiel0:

von setuptools importieren Einrichtung, Pakete_finden
Einrichtung(
    Name='Beispiel',
    Version='0.1.0',
    Pakete=Pakete_finden(include=['Beispielprojekt', 'beispielprojekt.*'])
)

Hier legen wir drei Dinge fest:

  • Der Name des Pakets. Das ist der Name, den pip für Ihr Paket verwenden wird. Dieser Name muss nicht mit dem Namen des Ordners übereinstimmen, in dem sich das Paket befindet, obwohl es verwirrend sein kann, wenn dies nicht der Fall ist. Ein Beispiel dafür, dass der Paketname und das Verzeichnis nicht übereinstimmen, ist Scikit-Learn: Sie installieren es über pip install scikit-learn, während Sie es durch Importieren aus sklearn verwenden.
  • Die Version Ihres Pakets. Dies ist die Version, die pip meldet. Sie wird zum Beispiel verwendet, wenn Sie Ihr Paket auf PyPI1 veröffentlichen.
  • Welche Pakete eingeschlossen werden sollen; in unserem Fall ist dies nur exampleproject/. Hier lassen wir setuptools dies automatisch herausfinden2. Obwohl Sie find_packages() im Prinzip auch ohne Argumente verwenden können, kann dies möglicherweise dazu führen, dass unerwünschte Pakete eingeschlossen werden. Das kann zum Beispiel passieren, wenn Sie ein __init__.py in Ihr tests/ Verzeichnis aufnehmen. Alternativ können Sie auch das Argument exclude verwenden, um die Aufnahme von Tests in das Paket explizit zu verhindern, aber das ist etwas weniger robust.

Um Ihr Paket zu installieren, müssen Sie nun nur noch Folgendes aus dem Verzeichnis example_project/ 3 ausführen:

pip install -e .

. bezieht sich hier auf das aktuelle Arbeitsverzeichnis, von dem ich annehme, dass es das Verzeichnis ist, in dem setup.py zu finden ist. Die Markierung -e gibt an, dass wir im bearbeitbaren Modus installieren möchten. Das bedeutet, dass wir, wenn wir die Dateien in unserem Paket bearbeiten, das Paket nicht neu installieren müssen, bevor die Änderungen in Kraft treten. Sie müssen allerdings entweder Python neu starten oder das Paket neu laden!

Wenn Sie Informationen in setup.py selbst bearbeiten, müssen Sie das Paket in den meisten Fällen neu installieren, und auch, wenn Sie neue (Unter-)Pakete hinzufügen. Im Zweifelsfall kann es nie schaden, das Paket 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 requirements.txt Datei oder eine environment.yml verwendet, wenn Sie conda benutzen. Wenn Sie nun ein setup.py erstellen, können Sie Ihre Abhängigkeiten im Argument install_requires angeben. Für ein typisches Data-Science-Projekt könnten Sie zum Beispiel Folgendes haben:

Einrichtung(
    Name='Beispiel',
    Version='0.1.0',
    Pakete=Pakete_finden(include=['Beispielprojekt', 'beispielprojekt.*']),
    install_requires=[
        'PyYAML',
        pandas==0.23.3',
        'numpy>=1.14.5',
        'matplotlib>=2.2.0,,
 'jupyter'
 ]
 )

Sie können Anforderungen ohne eine Version angeben (PyYAML), eine Version festlegen (pandas==0.23.3), eine Mindestversion von angeben ('numpy>=1.14.5) oder einen Versionsbereich festlegen (matplotlib>=2.2.0,<3.0.0). Diese Anforderungen werden automatisch von pip installiert, wenn Sie Ihr Paket installieren.

Extras-erfordern

Manchmal haben Sie vielleicht 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, muss ich möglicherweise matplotlib und jupyter installiert haben, um interaktiv mit den Daten arbeiten und Visualisierungen der Leistung des Modells erstellen zu können. Andererseits möchte ich weder matplotlib noch jupyter auf dem Rechner (oder Container) installieren, auf dem ich trainiere oder Inferenzen durchführe, wenn das Modell in der Produktion läuft. Glücklicherweise erlaubt setuptools die Angabe optionaler Abhängigkeiten in extras_require:

Einrichtung(
    Name='Beispiel',
    Version='0.1.0',
    Pakete=Pakete_finden(include=['Beispielprojekt', 'beispielprojekt.*']),
    install_requires=[
        PyYAML'.,
        pandas==0.23.3',
        'numpy>=1.14.5'
    ],
    extras_require={
        'interaktiv': ['matplotlib>=2.2.0', 'jupyter'],
 }
 )

Wenn wir nun das Paket normal installieren (pip install example von PyPI oder pip install -e . lokal) , werden nur die Abhängigkeiten PyYAML, pandas und numpy installiert. Wenn wir jedoch angeben, dass wir die optionalen interactive Abhängigkeiten ( pip install "example[interactive]" oder pip install -e ".[interactive]"), dann matplotlib und jupyter werden ebenfalls installiert.

Skripte und Einstiegspunkte

Der Hauptanwendungsfall der meisten Python-Pakete, die Sie von PyPI installieren, ist die Bereitstellung von Funktionen , die in anderem Python-Code verwendet werden können. Mit anderen Worten, Sie können import von diesen Paketen aus nutzen. Als Datenwissenschaftler erstelle ich oft Pakete, die nicht dazu gedacht sind, von anderem Python-Code genutzt zu werden, sondern um etwas zu tun, zum Beispiel ein Modell zu trainieren. So habe ich oft ein Python-Skript, das ich von der Kommandozeile aus ausführen möchte.

Der beste Weg4, um die Funktionalität Ihres Pakets für die Kommandozeile freizugeben, besteht darin, und entry_point als solche zu definieren:

Einrichtung(
    # ...,
    Einstiegspunkte={
        'console_scripts': ['mein-befehl=exampleproject.example:main']
    }
)

Jetzt können Sie den Befehl my-command von der Kommandozeile aus verwenden, der wiederum die main Funktion innerhalb von exampleproject/example.py. Vergessen Sie nicht, neu zu installieren - sonst wird der Befehl nicht registriert.

Tests

Wann immer Sie einen Code schreiben, empfehle ich Ihnen dringend, auch Tests für diesen Code zu schreiben. Zum Testen von mit Python empfehle ich Ihnen pytest. Natürlich sollten Sie pytest nicht zu Ihren Abhängigkeiten in install_requires hinzufügen: es wird von den Benutzern Ihres Pakets nicht benötigt. Damit es automatisch installiert wird , wenn Sie Tests durchführen, können Sie Folgendes zu setup.py hinzufügen:

Einrichtung(
    # ...,
    setup_requires=['pytest-runner'],
    tests_erforderlich=['pytest'],
)

Zusätzlich müssen Sie eine Datei namens setup.cfg mit folgendem Inhalt erstellen:

[Alias]
Test=pytest

Jetzt können Sie einfach python setup.py test ausführen und setuptools stellt sicher, dass die notwendigen Abhängigkeiten installiert sind und führt pytest für Sie aus! Werfen Sie einen Blick auf , wenn Sie Argumente angeben oder Konfigurationsoptionen für pytest festlegen möchten.

Wenn Sie zusätzliche Anforderungen für das Testen haben (z.B. pytest-flask), können Sie diese auf tests_require hinzufügen.

Flocke8

Ich persönlich halte es für eine gute Idee, Flake8 auszuführen, um die Formatierung Ihres Codes zu überprüfen. Genau wie bei pytest sollten Sie flake8 nicht in die install_requires Abhängigkeiten: Es muss nicht installiert werden, um Ihr Paket zu verwenden. Stattdessen können Sie es zu setup_requires hinzufügen:

Einrichtung(
    # ...,
    setup_requires=['Flocke8']
)

Jetzt können Sie einfach python setup.py flake8 ausführen. Natürlich können Sie auch die Version von flake8 (oder jedes andere Paket) in setup_requires pinnen.

Wenn Sie einige der Konfigurationsparameter von Flake8 ändern möchten, können Sie unter einen Abschnitt [flake8] zu Ihrem setup.cfg hinzufügen. Zum Beispiel:

[flake8]
max-line-length=120

Paketdaten

Manchmal möchten Sie vielleicht einige Nicht-Python-Dateien in Ihr Paket aufnehmen. Bei diesen kann es sich zum Beispiel um Schemadateien oder eine kleine Nachschlagetabelle handeln. Beachten Sie, dass solche Dateien zusammen mit Ihrem Code verpackt werden. Daher ist es im Allgemeinen eine schlechte Idee, große Dateien einzubinden.

Nehmen wir an, wir haben ein schema.json in unserem Projekt, das wir in exampleproject/data/schema.json ablegen. Wenn wir es in unser Paket aufnehmen wollen, müssen wir das Argument package_data von setup verwenden:

Einrichtung(
    # ...,
    Paket_Daten={'Beispielprojekt': ['data/schema.json']}
)

Dadurch wird sichergestellt, dass die Datei in das Paket aufgenommen wird. Wir können auch wählen, dass alle Dateien nach einem bestimmten Muster enthält:

Einrichtung(
    # ...,
    Paket_Daten={'': ['*.json']}
)

Dies fügt alle *.json Dateien in jedem Paket hinzu, auf das es trifft.

Versuchen Sie jetzt nicht, den Speicherort der installierten Dateien selbst herauszufinden, denn pkg_resources verfügt über einige sehr praktische Komfortfunktionen:

  • pkg_resources.resource_stream liefert Ihnen einen Stream der Datei, ähnlich wie das Objekt, das Sie erhalten, wenn Sie open() aufrufen,
  • pkg_resources.resource_string erhalten Sie den Inhalt der Datei als Zeichenkette,
  • pkg_resources.resource_filename gibt Ihnen den Dateinamen der Datei (und extrahiert in eine temporäre Datei, wenn sie in einem gepackten Paket enthalten ist), wenn die beiden oben genannten Optionen nicht Ihren Anforderungen entsprechen.

Wir könnten zum Beispiel unser Schema einlesen, indem wir:

von json importieren laden
von pkg_resources importieren ressource_strom

Schema = laden(ressource_strom('Beispielprojekt', 'data/schema.json'))

Metadaten

Wenn Sie Ihr Paket veröffentlichen, möchten Sie Ihren potenziellen Nutzern wahrscheinlich einige weitere Informationen über Ihr Paket geben, darunter eine Beschreibung, den Namen des Autors oder Betreuers und die URL zur Homepage des Pakets. Eine vollständige Liste aller zulässigen Metadaten finden Sie in den setuptools docs.

Wenn Sie bei PyPI veröffentlichen, möchten Sie vielleicht auch den Inhalt Ihres README.md automatisch in die long_description laden und Klassifizierer bereitstellen, die pip noch mehr über Ihr Paket verraten.

Nachbereitung

Dieser Blog sollte ein guter Ausgangspunkt sein, um die meisten Ihrer Python-Projekte einzurichten. Wenn Sie mehr über Python-Paketierung lesen möchten, werfen Sie einen Blick in die Dokumentation. Hier ist ein Beispiel setup.py , das alle in diesem Blog gezeigten Teile kombiniert:

von setuptools importieren Einrichtung, Pakete_finden

Einrichtung(
    Name='Beispiel',
    Version='0.1.0',
    Beschreibung='Ein Python-Paket einrichten'.,
    Autor=Rogier van der Geer'.,
    autor_email='rogiervandergeer@xebia.com',
    url='https://xebia.com/blog/setup-py',
    Pakete=Pakete_finden(include=['Beispielprojekt', 'beispielprojekt.*']),
    install_requires=[
        'PyYAML',
        pandas==0.23.3',
        'numpy>=1.14.5'
    ],
    extras_require={'Plotten': ['matplotlib>=2.2.0', 'jupyter']},
    setup_requires=['pytest-runner', 'Flocke8'],
    tests_erforderlich=['pytest'],
    Einstiegspunkte={
        'console_scripts': ['mein-befehl=exampleproject.example:main']
    },
    Paket_Daten={'Beispielprojekt': ['data/schema.json']}
)

und die dazugehörige setup.cfg:

[Alias]
Test=pytest

[flake8]
max-line-length=120

Verbessern Sie Ihre Python-Kenntnisse, lernen Sie von den Experten!

Bei GoDataDriven bieten wir eine Vielzahl von Python-Kursen für Anfänger und Experten an, die von den besten Fachleuten auf diesem Gebiet unterrichtet werden. Kommen Sie zu uns und verbessern Sie Ihr Python-Spiel:

Fußnoten

0: In diesem Blog habe ich setuptools verwendet, um mein Beispielprojekt einzurichten. Alternativ könnten Sie auch distutils verwenden, das Standardwerkzeug für die Paketierung in Python, dem aber Funktionen wie die find_packages() Funktion und entry_points fehlen. Da die Verwendung von setuptools heutzutage sehr verbreitet ist und viele seiner Funktionen besonders nützlich sein können, schlage ich vor, dass Sie setuptools verwenden sollten.

1: Wenn Sie möchten, dass die Version Ihres Pakets auch innerhalb von Python verfügbar ist, schauen Sie hier nach: .

2: Sie könnten Ihre Pakete auch manuell auflisten, aber das ist besonders fehleranfällig.

3: Alternativ können Sie auch python setup.py install verwenden, aber die Verwendung von pip hat viele Vorteile, unter anderem die automatische Installation von Abhängigkeiten und die Möglichkeit, Ihr Paket zu deinstallieren oder zu aktualisieren.

4: Sie könnten auch das Argument scripts verwenden (ein Beispiel finden Sie hier: ) . Da Sie dafür jedoch ein Python-Shell-Skript erstellen müssen, funktioniert unter Windows möglicherweise nicht so gut (oder überhaupt nicht).

 

Verfasst von

Rogier van der Geer

Contact

Let’s discuss how we can support your journey.