Skip to content

Requirements.txt vs. setup.py

Wir würden uns über Ihre Unterstützung freuen, um unsere Beiträge mit Bezug zur Informatik zu verbreiten.

Lösung:

requirements.txt:

Dies hilft Ihnen, Ihre Entwicklungsumgebung einzurichten.

Programme wie pip können verwendet werden, um alle in der Datei aufgeführten Pakete auf einen Schlag zu installieren. Danach können Sie mit der Entwicklung Ihres Python-Skripts beginnen. Besonders nützlich, wenn Sie planen, andere an der Entwicklung teilhaben zu lassen oder virtuelle Umgebungen zu verwenden.
So verwenden Sie es:

pip install -r requirements.txt

setup.py:

Dies hilft Ihnen, Pakete zu erstellen, die Sie weitergeben können.

Die setup.py Skript ist dazu gedacht, Ihr Paket auf dem System des Endbenutzers zu installieren, nicht um die Entwicklungsumgebung vorzubereiten, wie pip install -r requirements.txt tut. Siehe diese Antwort für weitere Details zu setup.py.


Die Abhängigkeiten Ihres Projekts sind in beiden Dateien aufgeführt.

Die kurze Antwort ist, dass requirements.txt nur zur Auflistung der Paketanforderungen dient. setup.py hingegen ist eher ein Installationsskript. Wenn Sie nicht vorhaben, den Python-Code zu installieren, benötigen Sie normalerweise nur requirements.txt.

Die Datei setup.py beschreibt, zusätzlich zu den Paketabhängigkeiten, den Satz von Dateien und Modulen, die gepackt (oder kompiliert, im Fall von nativen Modulen (d.h. in C geschrieben)) werden sollen, und Metadaten, die zu den Python-Paketlisten hinzugefügt werden sollen (z.B. Paketname, Paketversion, Paketbeschreibung, Autor, ...).

Da beide Dateien Abhängigkeiten auflisten, kann dies zu ein wenig Doppelarbeit führen. Lesen Sie unten für Details.

Anforderungen.txt


Diese Datei listet die Anforderungen an Python-Pakete auf. Es handelt sich um eine einfache Textdatei (optional mit Kommentaren), die das Paket auflistet Abhängigkeiten deines Python-Projekts auflistet (eine pro Zeile). Sie macht nicht die Art und Weise, wie Ihr Python-Paket installiert wird. Im Allgemeinen würde man die Anforderungsdatei mit pip install -r requirements.txt.

Der Dateiname der Textdatei ist willkürlich, lautet aber oft requirements.txt nach Konvention. Wenn man die Quellcode-Repositories anderer Python-Pakete untersucht, stößt man vielleicht auf andere Namen, wie z.B. dev-dependencies.txt oder dependencies-dev.txt. Diese dienen dem gleichen Zweck wie dependencies.txt dienen demselben Zweck wie dependencies.txt, führen aber im Allgemeinen zusätzliche Abhängigkeiten auf, die für die Entwickler des jeweiligen Pakets von Interesse sind, nämlich für das Testen des Quellcodes (z.B. pytest, pylint, etc.) vor der Veröffentlichung. Benutzer des Pakets benötigen im Allgemeinen nicht den gesamten Satz an Entwicklerabhängigkeiten, um das Paket auszuführen.

Wenn mehrere requirements-X.txt Varianten vorhanden sind, dann listet normalerweise eine die Laufzeit-Abhängigkeiten auf und die andere die Build-Zeit- oder Test-Abhängigkeiten. Einige Projekte kaskadieren auch ihre Anforderungsdatei, d.h. wenn eine Anforderungsdatei eine andere Datei einschließt (Beispiel). Auf diese Weise können Wiederholungen reduziert werden.

setup.py


Dies ist ein Python-Skript, das die setuptools Modul verwendet, um ein Python-Paket zu definieren (Name, enthaltene Dateien, Paket-Metadaten und Installation). Es wird, wie requirements.txtauch die Laufzeit-Abhängigkeiten des Pakets auf. Setuptools ist der de-facto Weg, um Python-Pakete zu bauen und zu installieren, aber es hat seine Mängel, die im Laufe der Zeit die Entwicklung neuer "Meta-Paketmanager", wie pip, hervorgebracht haben. Beispiele für Unzulänglichkeiten von setuptools sind die Unfähigkeit, mehrere Versionen desselben Pakets zu installieren, und das Fehlen eines Deinstallationsbefehls.

Wenn ein Python-Benutzer den Befehl pip install ./pkgdir_my_module (oder pip install my-module), führt pip setup.py in dem angegebenen Verzeichnis (oder Modul). In ähnlicher Weise wird jedes Modul, das ein setup.py sein kann pip-installiert werden, z.B. durch Ausführen von pip install . aus dem gleichen Ordner.

Brauche ich wirklich beides?


Die kurze Antwort ist nein, aber es ist schön, beides zu haben. Sie erfüllen unterschiedliche Zwecke, aber sie können beide verwendet werden, um Ihre Abhängigkeiten aufzulisten.

Es gibt einen Trick, den Sie in Betracht ziehen können, um zu vermeiden, dass Ihre Liste der Abhängigkeiten doppelt vorhanden ist requirements.txt und zu vermeiden. setup.py. Wenn Sie eine vollständig funktionierende setup.py für Ihr Paket bereits geschrieben haben und Ihre Abhängigkeiten größtenteils extern sind, könnten Sie eine einfache requirements.txt mit nur dem Folgenden:

 # requirements.txt
 #
 # installs dependencies from ./setup.py, and the package itself,
 # in editable mode
 -e .

 # (the -e above is optional). you could also just install the package
 # normally with just the line below (after uncommenting)
 # .

Die -e ist eine besondere pip install Option, die das angegebene Paket in editierbar Modus installiert. Wenn pip -r requirements.txt auf diese Datei ausgeführt wird, installiert pip Ihre Abhängigkeiten über die Liste in ./setup.py. Die editierbare Option legt einen Symlink in Ihrem Installationsverzeichnis ab (anstelle eines Eies oder einer archivierten Kopie). Sie ermöglicht es Entwicklern, Code an Ort und Stelle aus dem Repository zu bearbeiten, ohne ihn neu zu installieren.

Sie können auch die Vorteile der sogenannten "setuptools extras" nutzen, wenn Sie beide Dateien in Ihrem Paket-Repository haben. Sie können optionale Pakete in setup.py unter einer benutzerdefinierten Kategorie definieren und diese Pakete aus genau dieser Kategorie mit pip installieren:

# setup.py
from setuptools import setup
setup(
   name="FOO"
   ...
   extras_require = {
       'dev': ['pylint'],
       'build': ['requests']
   }
   ...
)

und dann in der Anforderungsdatei:

# install packages in the [build] category, from setup.py
# (path/to/mypkg is the directory where setup.py is)
-e path/to/mypkg[build]

Dies würde alle Ihre Abhängigkeitslisten innerhalb von setup.py halten.

Beachten Sie .: Normalerweise würden Sie pip und setup.py aus einer Sandbox heraus ausführen, wie z.B. mit dem Programm virtualenv. Dadurch wird die Installation von Python-Paketen außerhalb des Kontexts der Entwicklungsumgebung Ihres Projekts vermieden.

Der Vollständigkeit halber, hier ist, wie ich es sehe, in 3 4 verschiedene Blickwinkel.

  1. Die Zwecke der Gestaltung sind unterschiedlich

Dies ist die genaue Beschreibung aus der offiziellen Dokumentation (Hervorhebung von mir):

Während install_requires (in setup.py) die Abhängigkeiten definiert. für ein einzelnes Projekt definiert, werden Requirements Files oft verwendet, um die Anforderungen zu definieren für eine komplette Python-Umgebung.

Während die install_requires-Anforderungen minimal sind, enthalten Requirements-Dateien oft eine ausführliche Auflistung der angehefteten Versionen, um wiederholbare Installationen einer kompletten Umgebung zu erreichen.

Da das aber vielleicht immer noch nicht ganz einfach zu verstehen ist, folgen im nächsten Abschnitt 2 sachliche Beispiele, die zeigen sollen, wie die beiden Ansätze unterschiedlich eingesetzt werden sollen.

  1. Ihre tatsächliche Verwendung ist also (angeblich) unterschiedlich
  • Wenn Ihr Projekt foo als eigenständige Bibliothek veröffentlicht werden soll (d.h. andere würden es wahrscheinlich import foo), dann würden Sie (und Ihre nachgelagerten Benutzer) eine flexible Deklaration von Abhängigkeiten haben wollen, so dass Ihre Bibliothek nicht "wählerisch" sein würde (und es auch nicht sein muss), welche genaue Version IHRER Abhängigkeiten sein sollte. Typischerweise würde Ihre setup.py also Zeilen wie diese enthalten:

         install_requires=[
             'A>=1,<2',
             'B>=2'
         ]
    
  • Wenn Sie nur irgendwie Ihre EXAKT aktuelle Umgebung für Ihre Anwendung "dokumentieren" oder "anheften" wollen bard.h., Sie oder Ihre Benutzer möchten Ihre Anwendung verwenden bar so wie sie ist, d.h. mit python bar.pyausführen, möchten Sie vielleicht Ihre Umgebung einfrieren, damit sie sich immer gleich verhält. In einem solchen Fall würde Ihre Anforderungsdatei wie folgt aussehen:

         A==1.2.3
         B==2.3.4
         # It could even contain some dependencies NOT strickly required by your library
         pylint==3.4.5
    
  1. Welche Datei soll ich in Wirklichkeit verwenden?

    • Wenn Sie eine Anwendung entwickeln bar die verwendet werden soll von python bar.pyverwendet werden soll, auch wenn es sich dabei "nur um ein Skript zum Spaß" handelt, wird empfohlen, die Datei requirements.txt zu verwenden, denn wer weiß, ob Sie nicht nächste Woche (zufällig ist Weihnachten) einen neuen Computer geschenkt bekommen, so dass Sie Ihre genaue Umgebung dort wieder einrichten müssen.

    • Wenn Sie eine Bibliothek entwickeln foo die verwendet werden soll von import fooverwendet wird, musst du eine setup.py vorbereiten. Punkt.
      Aber du kannst auch gleichzeitig eine requirements.txt bereitstellen, die das kann:

      (a) entweder in der A==1.2.3 Stil sein (wie in #2 oben erklärt);

      (b) oder enthält nur ein magisches einzelnes .

         .
      

      was in etwa gleichbedeutend wäre mit "installiere die Anforderungen basierend auf setup.py", jedoch ohne Duplikation. Ich persönlich bin der Meinung, dass dieser letzte Ansatz die Grenzen verwischt, zur Verwirrung beiträgt und KEINEN wirklichen Mehrwert bietet, aber es ist nichtsdestotrotz ein Trick, der von einem Ansatz abgeleitet ist, den der Python-Packaging-Maintainer Donald in seinem Blog-Post erwähnt.

  2. Unterschiedliche untere Schranken.

    Angenommen, es gibt eine bestehende engine Bibliothek mit dieser Geschichte:

    engine 1.1.0 Use steam
    ...
    engine 1.2.0 Internal combustion is invented
    engine 1.2.1 Fix engine leaking oil
    engine 1.2.2 Fix engine overheat
    engine 1.2.3 Fix occasional engine stalling
    
    engine 2.0.0 Introducing nuclear reactor
    

    Sie befolgen die obigen 3 Kriterien und haben korrekt entschieden, dass Ihre neue Bibliothek hybrid-engine eine setup.py verwendet, um ihre Abhängigkeit zu deklarieren engine>=1.2.0,<2zu deklarieren, und dann würde Ihre getrennte Anwendung reliable-car verwendet requirements.txt verwenden, um ihre Abhängigkeit zu deklarieren engine>=1.2.3,<2 (oder man kann auch einfach engine==1.2.3). Wie Sie sehen, ist die von Ihnen gewählte Zahl für die untere Grenze immer noch sehr unterschiedlich, und keine von ihnen verwendet die neueste engine==2.0.0. Und hier ist der Grund dafür.

    • hybrid-engine hängt ab von engine>=1.2.0 ab, denn das benötigte add_fuel() API wurde erstmals eingeführt in engine 1.2.0eingeführt, und diese Fähigkeit ist die Notwendigkeit von hybrid-engine, unabhängig davon, ob es in dieser Version einige (kleinere) Fehler gibt, die in den nachfolgenden Versionen 1.2.1, 1.2.2 und 1.2.3 behoben wurden.

    • reliable-car hängt ab von engine>=1.2.3 ab, da dies die früheste Version OHNE bekannte Probleme ist, bis jetzt. Natürlich gibt es in späteren Versionen neue Fähigkeiten, z.B. den "Kernreaktor", der in engine 2.0.0, aber sie sind nicht unbedingt wünschenswert für das Projekt reliable-car. (Ihr weiteres neues Projekt time-machine würde wahrscheinlich engine>=2.0.0verwenden, aber das ist ein anderes Thema.)

Wir zeigen Ihnen Rezensionen und Bewertungen

Denken Sie daran, dass Sie diese Chronik verbreiten können, wenn Sie Erfolg haben.



Nutzen Sie unsere Suchmaschine

Suche
Generic filters

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.