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.txt
auch 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.
- 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.
- 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 wahrscheinlichimport 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
bar
d.h., Sie oder Ihre Benutzer möchten Ihre Anwendung verwendenbar
so wie sie ist, d.h. mitpython bar.py
ausfü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
-
Welche Datei soll ich in Wirklichkeit verwenden?
-
Wenn Sie eine Anwendung entwickeln
bar
die verwendet werden soll vonpython bar.py
verwendet 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 vonimport foo
verwendet 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.
-
-
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
einesetup.py
verwendet, um ihre Abhängigkeit zu deklarierenengine>=1.2.0,<2
zu deklarieren, und dann würde Ihre getrennte Anwendungreliable-car
verwendetrequirements.txt
verwenden, um ihre Abhängigkeit zu deklarierenengine>=1.2.3,<2
(oder man kann auch einfachengine==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 neuesteengine==2.0.0
. Und hier ist der Grund dafür.-
hybrid-engine
hängt ab vonengine>=1.2.0
ab, denn das benötigteadd_fuel()
API wurde erstmals eingeführt inengine 1.2.0
eingeführt, und diese Fähigkeit ist die Notwendigkeit vonhybrid-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 vonengine>=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 inengine 2.0.0
, aber sie sind nicht unbedingt wünschenswert für das Projektreliable-car
. (Ihr weiteres neues Projekttime-machine
würde wahrscheinlichengine>=2.0.0
verwenden, 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.