Dies mag wie eine Anfängerfrage erscheinen, ist es aber nicht. Einige gängige Ansätze funktionieren nicht in allen Fällen:
sys.argv [0]
Dies bedeutet, dass Sie verwenden path = os.path.abspath(os.path.dirname(sys.argv[0]))
, dies funktioniert jedoch nicht, wenn Sie ein anderes Python-Skript in einem anderen Verzeichnis ausführen. Dies kann im wirklichen Leben passieren.
__Datei__
Dies bedeutet verwenden path = os.path.abspath(os.path.dirname(__file__))
, aber ich fand, dass dies nicht funktioniert:
py2exe
hat kein__file__
Attribut, aber es gibt eine Problemumgehung- Wenn Sie von IDLE mit ausführen,
execute()
gibt es kein__file__
Attribut - OS X 10.6 wo ich hinkomme
NameError: global name '__file__' is not defined
Verwandte Fragen mit unvollständigen Antworten:
- Python - Pfad zur ausgeführten Datei finden
- Der Pfad zur aktuellen Datei hängt davon ab, wie ich das Programm ausführe
- Woher weiß man den Pfad des laufenden Skripts in Python?
- Wechseln Sie in das Verzeichnis eines Python-Skripts
Ich suche nach einer generischen Lösung , die in allen oben genannten Anwendungsfällen funktioniert.
Aktualisieren
Hier ist das Ergebnis eines Testfalls:
Ausgabe von Python a.py (unter Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
a.py.
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
subdir / b.py.
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
Baum
C:.
| a.py
\---subdir
b.py
NameError: global name '__file__' is not defined
unter OS 10.6 eine Datei verwende und diese nicht im IDLE enthalten ist. Denken Sie, dass dies__file__
nur innerhalb von Modulen definiert ist.__file__
nichts mit Unicode zu tun. Ich weiß nicht, warum__file__
nicht definiert ist, aber ich suche nach einer generischen Lösung, die in allen Fällen funktioniert.some_path/module_locator.py
stattdessen den Standort geben ?Zunächst müssen Sie aus
inspect
und importierenos
Als nächstes verwenden Sie einfach, wo immer Sie die Quelldatei von Ihnen finden möchten
quelle
NameError: global name '__file__' is not defined
(eine andere Lösung hat dies verursacht).lambda:_
. Es hat bei mir funktioniert - ich bin mir nicht sicher, ob es immer funktionieren wird.lambda:0
läuft wahrscheinlich um einen unermesslich kleinen Betrag schneller (oder vielleicht nicht so klein ... könnte eine sofortige Ladung sein oder etwas noch schnelleres als0
eine globale Last für_
?). Es ist fraglich, ob es sauberer oder leichter zu lesen oder noch klüger / undurchsichtiger ist.getsourcefile(lambda:0)
ist bedeutungslos und wird nur zurückgegeben,None
wenn Sie versuchen, ihn an einer interaktiven Eingabeaufforderung auszuführen (da erlambda
in keiner Quelldatei enthalten ist.) Wenn Sie dies wissen möchten Woher kommt eine andere Funktion oder ein anderes Objekt in einer interaktiven Umgebungabspath(getsourcefile(thatFunctionOrObject))
? Vielleicht ist es für Sie hilfreicher?Diese Lösung ist auch in ausführbaren Dateien robust
quelle
entry_point: console_script
, aber keine der anderen Antworten.Ich hatte ein ähnliches Problem und denke, dies könnte das Problem lösen:
Es funktioniert für normale Skripte und im Leerlauf. Ich kann nur sagen, probieren Sie es für andere aus!
Meine typische Verwendung:
Jetzt benutze ich __modpath__ anstelle von __file__.
quelle
__modpath__
sollte also umbenannt werden. Sie brauchen dieglobal
Aussage wahrscheinlich auch nicht . Sonst +1!module_path()
. dhmodule_path(lambda _: None)
was nicht von den anderen Inhalten des Skripts abhängt, in dem es sich befindet.lambda _: None
und ihn fast die letzten zwei Jahre verwendet, aber gerade jetzt habe ich festgestellt, dass ich ihn auf nur reduzieren kannlambda:0
. Gibt es einen bestimmten Grund, warum Sie das Formular vorgeschlagen haben, mit einem ignorierten Argument von_
, anstatt überhaupt kein Argument? Gibt es etwas Überlegenes daran,None
wenn ein Leerzeichen vorangestellt wird und nicht nur0
? Sie sind beide gleich kryptisch, ich denke, nur einer ist 8 Zeichen lang, während der andere 14 Zeichen lang ist.lambda _:
es sich um eine Funktion handelt, die ein Argument akzeptiert undlambda:
keine. Es spielt keine Rolle, da die Funktion nie aufgerufen wird. Ebenso spielt es keine Rolle, welcher Rückgabewert verwendet wird. Ich denke, ich habe mich entschieden,None
weil es zu der Zeit darauf hindeutete, dass es sich um eine Funktion handelte, die nichts zu tun hatte und nie besser genannt werden sollte. Der Platz davor ist optional und wiederum nur zur besseren Lesbarkeit vorhanden (immer der Versuch, PEP8 zu folgen, ist gewohnheitsbildend).lambda
, es für etwas zu verwenden, für das es nie gedacht war. Wenn Sie PEP8 folgen sollten, denke ich , die richtigen Inhalte für sich wärenpass
, nichtNone
, aber es ist nicht gültig , eine Erklärung in einem setzenlambda
, so dass Sie in etwas mit einem Wert zu setzen haben. Es gibt ein paar gültige 2-Zeichen-Dinge, die Sie eingeben könnten, aber ich denke, die einzigen gültigen Einzelzeichen-Dinge, die Sie eingeben können, sind 0-9 (oder ein einzelner Zeichenvariablenname, der außerhalb von zugewiesen istlambda
). Ich denke, am0
besten zeigt das Nichts von 0- an. 9.Die kurze Antwort lautet: Es gibt keine garantierte Möglichkeit, die gewünschten Informationen zu erhalten. Es gibt jedoch Heuristiken, die in der Praxis fast immer funktionieren. Sie könnten sich ansehen, wie ich den Speicherort der ausführbaren Datei in C finde. . Es wird das Problem aus C-Sicht erörtert, aber die vorgeschlagenen Lösungen lassen sich leicht in Python übertragen.
quelle
In meiner Antwort auf die Frage Importieren von Modulen aus dem übergeordneten Ordner finden Sie verwandte Informationen, einschließlich der Frage , warum meine Antwort die unzuverlässige
__file__
Variable nicht verwendet . Diese einfache Lösung sollte mit verschiedenen Betriebssystemen wie den Modulenos
und kompatibel seininspect
Teil von Python sein.Zunächst müssen Sie Teile der Inspect- und OS- Module importieren .
Verwenden Sie als Nächstes die folgende Zeile an einer anderen Stelle in Ihrem Python-Code:
Wie es funktioniert:
Aus dem eingebauten Modul
os
(Beschreibung unten) wird dasabspath
Tool importiert.Dann wird
getsourcefile
(Beschreibung unten) aus dem eingebauten Modul importiertinspect
.abspath(path)
Gibt die absolute / vollständige Version eines Dateipfads zurückgetsourcefile(lambda:0)
Ruft irgendwie die interne Quelldatei des Lambda-Funktionsobjekts ab, kehrt also'<pyshell#nn>'
in der Python-Shell zurück oder gibt den Dateipfad des aktuell ausgeführten Python-Codes zurück.Wenn Sie
abspath
das Ergebnis von verwenden,getsourcefile(lambda:0)
sollten Sie sicherstellen, dass der generierte Dateipfad der vollständige Dateipfad der Python-Datei ist.Diese erläuterte Lösung basierte ursprünglich auf Code aus der Antwort unter Wie erhalte ich den Pfad der aktuell ausgeführten Datei in Python? .
quelle
Sie haben einfach angerufen:
anstatt:
abspath()
gibt Ihnen den absoluten Pfad vonsys.argv[0]
(den Dateinamen, in dem sich Ihr Code befindet) unddirname()
gibt den Verzeichnispfad ohne den Dateinamen zurück.quelle
Dies sollte den Trick plattformübergreifend ausführen (solange Sie nicht den Interpreter oder etwas anderes verwenden):
sys.path[0]
ist das Verzeichnis, in dem sich Ihr aufrufendes Skript befindet (der erste Ort, an dem nach Modulen gesucht wird, die von diesem Skript verwendet werden sollen). Wir können den Namen der Datei selbst am Ende vonsys.argv[0]
entfernen (was ich damit gemacht habeos.path.basename
).os.path.join
klebt sie einfach plattformübergreifend zusammen.os.path.realpath
Stellt nur sicher, dass wir immer noch den richtigen Namen des Skripts erhalten, wenn wir symbolische Links mit anderen Namen als dem Skript selbst erhalten.Ich habe keinen Mac. Also habe ich das nicht an einem getestet. Bitte lassen Sie mich wissen, ob es funktioniert, wie es scheint. Ich habe dies unter Linux (Xubuntu) mit Python 3.4 getestet. Beachten Sie, dass viele Lösungen für dieses Problem auf Macs nicht funktionieren (da ich gehört habe, dass
__file__
dies auf Macs nicht vorhanden ist).Beachten Sie, dass Ihr Skript, wenn es sich um eine symbolische Verknüpfung handelt, den Pfad der Datei angibt, mit der es verknüpft ist (und nicht den Pfad der symbolischen Verknüpfung).
quelle
Sie können
Path
aus dempathlib
Modul verwenden:Sie können call verwenden,
parent
um den Pfad weiter zu verfolgen:quelle
__file__
Variable, die unzuverlässig sein kann (nicht immer der vollständige Dateipfad, funktioniert nicht auf jedem Betriebssystem usw.), wie StackOverflow-Benutzer häufig erwähnt haben. Wenn Sie die Antwort so ändern, dass sie nicht enthalten ist, treten weniger Probleme auf und sie ist besser kompatibel. Weitere Informationen finden Sie unter stackoverflow.com/a/33532002/3787376 .Wenn der Code aus einer Datei stammt, können Sie den vollständigen Namen abrufen
Sie können den Funktionsnamen auch als abrufen
f_code.co_name
quelle
Fügen Sie einfach Folgendes hinzu:
Oder:
quelle
Meine Lösung ist:
quelle
quelle
'__file__'
sollte es keine Zeichenfolge sein, zweitens__file__
würde dies nur für die Datei funktionieren, in der sich diese Codezeile befindet, und nicht für die Datei, die ausgeführt wird?