Ich begann mit Python zu arbeiten. Ich habe requirements.txt
und setup.py
zu meinem Projekt hinzugefügt . Aber ich bin immer noch verwirrt über den Zweck beider Dateien. Ich habe gelesen, dass dies setup.py
für weiterverteilbare Dinge und requirements.txt
für nicht weiterverteilbare Dinge ausgelegt ist. Ich bin mir jedoch nicht sicher, ob dies korrekt ist.
Wie sollen diese beiden Dateien wirklich verwendet werden?
Antworten:
Anforderungen.txt
Dies hilft Ihnen beim Einrichten Ihrer Entwicklungsumgebung. Programme wie
pip
können verwendet werden, um alle in der Datei aufgelisteten Pakete auf einen Schlag zu installieren. Danach können Sie mit der Entwicklung Ihres Python-Skripts beginnen. Besonders nützlich, wenn Sie vorhaben, dass andere zur Entwicklung beitragen oder virtuelle Umgebungen verwenden. So verwenden Sie es:setup.py
Auf diese Weise können Sie Pakete erstellen, die Sie neu verteilen können. Dieses Skript soll Ihr Paket auf dem System des Endbenutzers installieren und die Entwicklungsumgebung nicht wie gewohnt vorbereiten
pip install -r requirements.txt
. Weitere Informationen zu setup.py finden Sie in dieser Antwort .Die Abhängigkeiten Ihres Projekts sind in beiden Dateien aufgeführt.
quelle
Die kurze Antwort lautet, dass
requirements.txt
nur die Paketanforderungen aufgelistet werden.setup.py
Auf der anderen Seite ähnelt es eher einem Installationsskript. Wenn Sie nicht vorhaben, den Python-Code zu installieren, benötigen Sie normalerweise nurrequirements.txt
.Die Datei
setup.py
beschreibt zusätzlich zu den Paketabhängigkeiten die Gruppe von Dateien und Modulen, die gepackt (oder kompiliert werden sollen, im Fall von nativen Modulen (dh in C geschrieben)) und Metadaten, die zu den Python-Paketlisten hinzugefügt werden sollen ( zB Paketname, Paketversion, Paketbeschreibung, Autor, ...).Da in beiden Dateien Abhängigkeiten aufgeführt sind, kann dies zu einer gewissen Duplizierung führen. Lesen Sie unten für Details.
Anforderungen.txt
Diese Datei listet die Anforderungen für Python-Pakete auf. Es ist eine einfache Textdatei (optional mit Kommentaren) , dass die Listen der Paketabhängigkeiten Ihrer Python - Projekt (eine pro Zeile). Es wird nicht beschrieben, wie Ihr Python-Paket installiert wird. Sie würden in der Regel die Anforderungsdatei mit verbrauchen
pip install -r requirements.txt
.Der Dateiname der Textdatei ist willkürlich, wird jedoch häufig
requirements.txt
durch Konvention festgelegt. Wenn Sie Quellcode-Repositorys anderer Python-Pakete durchsuchen, stoßen Sie möglicherweise auf andere Namen wiedev-dependencies.txt
oderdependencies-dev.txt
. Diese dienen demselben Zweck wiedependencies.txt
zusätzliche Abhängigkeiten, die für Entwickler des jeweiligen Pakets von Interesse sind, jedoch im Allgemeinen, um den Quellcode (z. B. Pytest, Pylint usw.) vor der Veröffentlichung zu testen. Benutzer des Pakets benötigen im Allgemeinen nicht den gesamten Satz von Entwicklerabhängigkeiten, um das Paket auszuführen.Wenn mehrere
requirements-X.txt
Varianten vorhanden sind, listet normalerweise eine Laufzeitabhängigkeiten und die andere Build-Time- oder Testabhängigkeit auf. Einige Projekte kaskadieren auch ihre Anforderungsdatei, dh wenn eine Anforderungsdatei eine andere Datei enthält ( Beispiel ). Dies kann die Wiederholung verringern.setup.py
Dies ist ein Python-Skript, das das
setuptools
Modul verwendet, um ein Python-Paket zu definieren (Name, enthaltene Dateien, Paketmetadaten und Installation). Es werdenrequirements.txt
auch Laufzeitabhängigkeiten des Pakets aufgelistet. Setuptools ist die de-facto-Methode zum Erstellen und Installieren von Python-Paketen, weist jedoch Mängel auf, die im Laufe der Zeit zur Entwicklung neuer "Meta-Paket-Manager" wie pip geführt haben. Beispielhafte Mängel von setuptools sind die Unfähigkeit, mehrere Versionen desselben Pakets zu installieren, und das Fehlen eines Deinstallationsbefehls.Wenn ein Python-Benutzer dies tut
pip install ./pkgdir_my_module
(oderpip install my-module
), wird pipsetup.py
in dem angegebenen Verzeichnis (oder Modul) ausgeführt. In ähnlicher Weise , die jedes Modul eine hatsetup.py
kannpip
durch Ausführen -Installierte, zBpip install .
aus dem gleichen Ordner.Brauche ich wirklich beides
Kurze Antwort ist nein, aber es ist schön, beides zu haben. Sie erfüllen unterschiedliche Zwecke, können jedoch beide zum Auflisten Ihrer Abhängigkeiten verwendet werden.
Es gibt einen Trick, den Sie in Betracht ziehen können, um zu vermeiden, dass Ihre Abhängigkeitsliste zwischen
requirements.txt
und dupliziert wirdsetup.py
. Wenn Sie bereits ein voll funktionsfähigessetup.py
Paket für Ihr Paket geschrieben haben und Ihre Abhängigkeiten größtenteils extern sind, können Sie ein einfachesrequirements.txt
mit nur den folgenden Optionen in Betracht ziehen :Dies
-e
ist eine speziellepip install
Option, mit der das angegebene Paket im bearbeitbaren Modus installiert wird . Wennpip -r requirements.txt
diese Datei ausgeführt wird, installiert pip Ihre Abhängigkeiten über die Liste in./setup.py
. Die bearbeitbare Option platziert einen Symlink in Ihrem Installationsverzeichnis (anstelle eines Eies oder einer archivierten Kopie). Entwickler können damit Code aus dem Repository bearbeiten, ohne ihn neu installieren zu müssen.Sie können auch die 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 nur dieser Kategorie mit pip installieren:
und dann in der Anforderungsdatei:
Dies würde alle Ihre Abhängigkeitslisten in setup.py behalten.
Hinweis : Normalerweise führen Sie pip und setup.py in einer Sandbox aus, z. B. mit dem Programm
virtualenv
. Dadurch wird vermieden, dass Python-Pakete außerhalb des Kontexts der Entwicklungsumgebung Ihres Projekts installiert werden.quelle
.
w / o-e
innenrequirements.txt
. Diese Methode delegiert nur alle Anforderungen ansetup.py
und Sie müssen niemanden in den bearbeitbaren Modus zwingen. Benutzer können weiterhin tun,pip install -e .
wenn sie möchten.-e .
verwendet auch setup.py, um Abhängigkeiten zu finden, verknüpft jedoch den aktuellen Ordner (an Ort und Stelle mit einem Symlink) im Ordner pip install, anstatt eine Kopie zu-e
erstellen. Dies wird im Allgemeinen nur verwendet, wenn Sie das Paket entwickeln. Mit-e
werden Änderungen an Ihren Python-Paketdateien (* .py) sofort in Ihrer Pip-Umgebung wirksam, anstatt die Neuinstallation des Pakets nach jeder Änderung erzwingen zu müssen.cd foo && pip install -r ./bar/requirements.txt
wird infoo/bar
oder nach setup.py gesuchtfoo
? Wenn letzteres der Fall ist, gibt es einen Weg, das erstere zu erreichen?pip -r REQ
kümmert sich nicht um das Verzeichnis, in dem sich REQ befindet. Sie können es von einem Fifo füttern, auch wenn Sie möchten :pip install -r <(echo "mylib1"; echo "mylib2";)
. Wo<(CMD)
ist die Bash-Befehlsersetzung, nicht die Standardumleitung?Der Vollständigkeit halber sehe ich es hier in
34 verschiedenen Winkeln.Dies ist die genaue Beschreibung aus der offiziellen Dokumentation (Schwerpunkt Mine):
Es ist jedoch möglicherweise immer noch nicht leicht zu verstehen. Im nächsten Abschnitt werden zwei sachliche Beispiele aufgeführt, um zu demonstrieren, wie die beiden Ansätze unterschiedlich verwendet werden sollen.
Ihre tatsächlichen Verwendungen sind daher (sollen) unterschiedlich
Wenn Ihr Projekt
foo
als eigenständige Bibliothek veröffentlicht werden soll (was wahrscheinlich andere tun würdenimport foo
), möchten Sie (und Ihre nachgeschalteten Benutzer) eine flexible Abhängigkeitserklärung haben, damit Ihre Bibliothek dies nicht tut (und dies auch nicht muss) ) Seien Sie "wählerisch", wie genau Ihre Abhängigkeiten aussehen sollen. Normalerweise enthält Ihre setup.py folgende Zeilen:Wenn Sie Ihre EXAKTE aktuelle Umgebung für Ihre Anwendung nur irgendwie "dokumentieren" oder "anheften" möchten
bar
, dh Sie oder Ihre Benutzer möchten Ihre Anwendungbar
unverändert verwenden, dh ausführenpython bar.py
, möchten Sie möglicherweise Ihre Umgebung einfrieren, damit sie einfriert würde sich immer gleich verhalten. In diesem Fall würde Ihre Anforderungsdatei folgendermaßen aussehen:Welches verwende ich in Wirklichkeit?
Wenn Sie eine Anwendung entwickeln,
bar
die von verwendet wirdpython bar.py
, auch wenn dies "nur zum Spaß ein Skript" ist, wird Ihnen dennoch empfohlen, die Datei "resources.txt" zu verwenden, da Sie, wer weiß, nächste Woche (was zufällig Weihnachten ist) eine erhalten würden neuer Computer als Geschenk, daher müssten Sie dort Ihre genaue Umgebung erneut einrichten.Wenn Sie eine Bibliothek entwickeln,
foo
die von verwendet wirdimport foo
, müssen Sie eine setup.py vorbereiten. Zeitraum. Sie können sich jedoch auch dafür entscheiden, gleichzeitig eine require.txt bereitzustellen, die Folgendes kann:(a) entweder im
A==1.2.3
Stil sein (wie in # 2 oben erklärt);(b) oder nur eine magische Single enthalten
.
Dies würde in etwa "Installieren der Anforderungen basierend auf setup.py" ohne Duplizierung bedeuten. Persönlich denke ich, dass dieser letzte Ansatz die Linie verwischt, die Verwirrung erhöht und NICHT wirklich einen Mehrwert schafft, aber dennoch ein Trick ist, der aus einem Ansatz abgeleitet wurde, den Python-Verpackungsbetreuer Donald in seinem Blogbeitrag erwähnt hat .
Unterschiedliche Untergrenzen.
Selbst nachdem Sie die oben genannten 3 Kriterien befolgt und richtig entschieden haben, dass Ihre Bibliothek a
hybrid-engine
verwendetsetup.py
, um ihre Abhängigkeit zu deklarierenengine>=1.2.0
, und Ihre Beispielanwendungreliable-car
verwendetrequirements.txt
, um ihre Abhängigkeit zu deklarierenengine>=1.2.3
, obwohl die neueste Version vonengine
bereits 1.4.0 ist. Wie Sie sehen, unterscheidet sich Ihre Wahl für die Anzahl der unteren Grenzen immer noch geringfügig. Und hier ist warum.hybrid-engine
hängt davon abengine>=1.2.0
, dass hypothetisch gesehen die erforderliche Fähigkeit zur "internen Verbrennung" erstmals eingeführtengine 1.2.0
wurde und diese Fähigkeit die Notwendigkeit isthybrid-engine
, unabhängig davon, ob in einer solchen Version einige (geringfügige) Fehler vorhanden sind und in nachfolgenden Versionen 1.2.1 behoben wurden , 1.2.2 und 1.2.3.reliable-car
hängt davon ab,engine>=1.2.3
da dies die früheste Version OHNE bekannte Probleme ist. Sicher, in späteren Versionen gibt es neue Funktionen, z. B. "Elektromotor"engine 1.3.0
und "Kernreaktor"engine 1.4.0
, aber sie sind für das Projekt nicht erforderlichreliable-car
.quelle
A==1.2.3
, und wenn das Downstream-Paket Ihrer Bibliothek davon abhängtA==1.2.4
, gibt es jetzt keine Möglichkeit, beide zu erfüllen. Die Lösung zur Minimierung dieses Konflikts besteht darin, dass Ihre Bibliothek einen Bereich definiert, von dem Sie wissen, dass er funktionieren würde. Angenommen, viele Upstream-Bibliotheken folgen bereits semver.org ,A>=1,<2
würde funktionieren.foo
nichtimport foo
Ihnen geben? Diese hackig akzeptierten Antworten in dem von Ihnen angegebenen Link sind ein perfektes Beispiel dafür, warum Paketbetreuer "nicht wählerisch sein sollten und dürfen". :-) Darf ich jetzt deine Gegenstimme haben?