Unterschied zwischen entry_points / console_scripts und Skripten in setup.py?

75

Grundsätzlich gibt es zwei Möglichkeiten, Python-Konsolenskripte auf meinem Pfad zu installieren setup.py:

setup(
    ...
    entry_points = {
        'console_scripts': [
            'foo = package.module:func',
        ],
    }
)

und

setup(
    ...
    scripts = [
        'scripts/myscript.sh'
    ]
)

Was sind die Unterschiede? Ich sehe, dass der erste Ansatz es mir ermöglicht, einen schönen, spezifischen Namen für mein Skript zu wählen, aber gibt es noch andere Unterschiede? Unterschiedliche ursprüngliche Zwecke, Kompatibilität (Setuptools, Distutils, ...?), Verwendung, ...? Ich bin ziemlich verwirrt und eine nette, ausgearbeitete Antwort könnte mir (und wahrscheinlich auch anderen) helfen, all dies richtig zu verstehen.

Update: Da ich die Frage gestellt PyPA veröffentlicht diese kühlen Dokumente zum Thema .

Honza Javorek
quelle
1
Der [Update] -Link ist defekt. Ich glaube , packaging.python.org/distributing/#scripts ist der Ersatz (?)
matt wilkie
1
Ja, danke für die Benachrichtigung. Ich werde das Update aktualisieren :)
Honza Javorek

Antworten:

43

Die Dokumente für das (fantastische) Click-Paket enthalten einige Gründe , Einstiegspunkte anstelle von Skripten zu verwenden, einschließlich

  1. plattformübergreifende Kompatibilität und
  2. Vermeiden Sie die Zuweisung __name__durch den Interpreter __main__, da dies dazu führen kann, dass Code zweimal importiert wird (wenn ein anderes Modul Ihr Skript importiert).

Click ist eine entry_pointsgute Möglichkeit, Funktionen für die Verwendung als zu implementieren.

jfeala
quelle
10
Das ist die richtige Antwort. Grundsätzlich gab es dort viele Probleme mit den alten Distutils. Eine Menge wirklich kluger Leute haben Setuptools entwickelt, um sie zu ersetzen. Sie haben zusammengearbeitet und den Mechanismus entry_points / console_scripts als Standard für die Verteilung ausführbarer Dateien entwickelt, damit Sie nicht über die Probleme mit allen anderen Optionen nachdenken müssen. Sei kein Held. Verwenden Sie, was Ihnen gegeben wurde.
Bruno Bronosky
Ich möchte hinzufügen, dass, seit ich die Frage gestellt habe, diese großartigen Dokumente aufgetaucht sind: python-packaging-user-guide.readthedocs.org/en/latest/…
Honza Javorek
Leider @HonzaJavorek - diese "fantastischen Dokumente" sind jetzt ein 404 / nicht vorhanden: /
Dan
Sie existieren, nur die Struktur hat sich geändert. Neuer Link: python-packaging-user-guide.readthedocs.io/search/?q=scripts
Honza Javorek
1
Können Sie "zweimal importiert" näher erläutern? Ich hatte den Eindruck, dass "if name == ' main ': '" verwendet wird, um dieses Problem zu lösen?
Tribbloid
14

Ein wesentlicher Unterschied zwischen diesen beiden Methoden zum Erstellen von ausführbaren Befehlszeilendateien besteht darin, dass Sie beim setuptoolsAnsatz (Ihrem ersten Beispiel) eine Funktion innerhalb des Skripts aufrufen müssen - in Ihrem Fall ist dies die funcInnenseite Ihrer module. Im distutilsAnsatz (Ihrem zweiten Beispiel) rufen Sie das Skript jedoch direkt auf (wodurch eine Auflistung mit oder ohne Erweiterung möglich ist).

plessthanpt05
quelle
9
Ich denke, diese Antwort verfehlt den Hauptpunkt. Der entry_point-Ansatz ist der neue Weg, den wir alle verwenden sollten. Immer wenn es eine Setuptool-Alternative zu einer Distutils-Funktionalität gibt, hat dies einen sehr guten Grund.
Bruno Bronosky
4
Alternativ scheint dies scriptsdie einzige Möglichkeit zu sein, ein benutzerdefiniertes Skript einzuschließen, beispielsweise ein WSGI-Skript anstelle eines Befehlszeilenskripts. entry_pointsgeneriert immer eine ausführbare Befehlszeile. (Ob das eine gute Idee ist, weiß ich nicht
genau
8

Der Einstiegspunktansatz für Setup-Tools (Nr. 1) hat auch den Vorteil, dass unter Windows eine EXE-Datei erstellt wird, die wie ein normales Windows-Programm doppelt angeklickt und aufgerufen werden kann. Dies ist zusätzlich dazu, dass auf posix-ähnlichen Systemen ein Skript im Bin-Pfad abgelegt wird.

Kaushik Ghose
quelle
2

Ein weiterer Unterschied besteht darin, dass bei Verwendung von console_scripts die Init- Datei meines Moduls ausgeführt wurde. Wenn nur Skripte verwendet wurden, wurde das Modul init nicht ausgeführt, sondern nur das Skript.

Raumhalter
quelle