Seite 1 von 1

Wie mit ausführbarer Datei für eigene Bibliothek umgehen?

Verfasst: Samstag 30. Juli 2011, 06:57
von snafu
Ich habe meinem Projekt Launchit nun eine ausführbare Datei spendiert, welche einfach ein Python-Skript ohne `.py`-Endung ist und im Verzeichnis `bin` direkt unterhalb des Wurzelverzeichnisses liegt. Dieses Skript führt letztlich die `gui.main()` aus.

Da es derzeit noch kein Installationsskript für das Paket gibt und weil ich auch später den Anwender nicht dazu zwingen möchte, Launchit komplett zu installieren, wenn er es eigentlich nur mal aus dem Repo zum Ausprobieren aufrufen will, behelfe ich mir mit ein paar Zeilen zusätzlichem Code, um Launchit importieren zu können, obwohl die besagte Datei selbst nicht Teil eines Pakets ist (keine `__init__.py`). Dazu setze ich beim Aufruf des Executables einfach das darüberliegende Verzeichnis an den Anfang von `sys.path` und mache den Import von Launchit anschließend.

So weit, so gut. Was mich jetzt aber stört, ist der Gedanke, wenn es das Skript irgendwann mal als installierte Variante a la `/usr/bin/launchit` gibt. In diesem Fall würde es unsinnigerweise das darüberliegende Verzeichnis `/usr` in `sys.path` setzen, was von Pythons Import-Mechanismus zwar lautlos übergangen werden müsste, aber ja irgendwie trotzdem doof ist. Gibt es dafür irgendein besseres Vorgehen? Ist vielleicht auch meine Idee an sich schon blöde?

Ich freue mich auf eure Vorschläge. :)

Achso, hier die Umsetzung zum Zeitpunkt als der Beitrag verfasst wurde: https://github.com/seblin/launchit/blob ... n/launchit

Re: Wie mit ausführbarer Datei für eigene Bibliothek umgehen

Verfasst: Samstag 30. Juli 2011, 09:10
von Darii
Ich würde einfach direkt versuchen launchit zu importieren

Code: Alles auswählen

#!/usr/bin/env python
try:
    import launchit
except ImportError:
    def add_dev_path():
        import os, sys
        module_dir = os.path.dirname(__file__)
        new_path = os.path.join(module_dir, "..")
        sys.path.append(package_path)
    add_dev_path()    
    import launchit

launchit.gui.main()

Re: Wie mit ausführbarer Datei für eigene Bibliothek umgehen

Verfasst: Samstag 30. Juli 2011, 09:38
von snafu
@Darii: Dann würde das Executable grundsätzlich die installierte Version von Launchit benutzen, sobald eine vorhanden ist. Das möchte ich eigentlich vermeiden, da es sicher irritierend wäre, wenn jemand irgendwann mal ein Release von Launchit installiert hätte und 3 Monate später den Stand im Repo testen möchte. Denn auch wenn Python-Importe an sich anderen Regeln folgen, so würde ich als unbedarfter User schon erwarten, dass ein "Binary" diejenige Version einer Bibliothek benutzt, zu der es sozusagen gehört.

//edit: Blödsinn. Auch Python-Importe bevorzugen natürlich lokale Modul-Namen vor globalen Namen, da das aktuelle Verzeichnis ja standardmäßig ganz am Anfang des Python-Path steht und damit auch zuerst durchsucht wird. :oops:

Re: Wie mit ausführbarer Datei für eigene Bibliothek umgehen

Verfasst: Samstag 30. Juli 2011, 09:43
von Darii
Dann dreh die Logik halt um und mach ein os.path.exists vor dem sys.path.append

Re: Wie mit ausführbarer Datei für eigene Bibliothek umgehen

Verfasst: Sonntag 31. Juli 2011, 12:56
von snafu
Ich prüfe jetzt einfach, ob der übergeordnete Pfad ein Unterverzeichnis namens `launchit` hat und setze den übergeordneten Pfad nur dann ein:

Code: Alles auswählen

path = os.path.join(os.path.dirname(__file__), '..')
if os.path.isdir(os.path.join(path, 'launchit')):
    sys.path.insert(0, os.path.abspath(path))

import launchit
launchit.gui.main()
Die Annahme "Ein-Paket-Ist-Ein-Verzeichnis" halte ich erstmal für ausreichend. Wir wollen ja nicht übertreiben. :)