Ich habe früher Dateien geöffnet, die sich im selben Verzeichnis wie das aktuell ausgeführte Python-Skript befanden, indem ich einfach einen Befehl wie verwendet habe
open("Some file.txt", "r")
Ich stellte jedoch fest, dass beim Ausführen des Skripts in Windows durch Doppelklicken versucht wurde, die Datei aus dem falschen Verzeichnis zu öffnen.
Seitdem habe ich einen Befehl des Formulars verwendet
open(os.path.join(sys.path[0], "Some file.txt"), "r")
wann immer ich eine Datei öffnen wollte. Dies funktioniert für meine spezielle Verwendung, aber ich bin nicht sicher, ob sys.path[0]
es in einem anderen Anwendungsfall fehlschlagen könnte.
Meine Frage lautet also: Was ist der beste und zuverlässigste Weg, um eine Datei zu öffnen, die sich im selben Verzeichnis befindet wie das aktuell ausgeführte Python-Skript?
Folgendes konnte ich bisher herausfinden:
os.getcwd()
undos.path.abspath('')
geben Sie das "aktuelle Arbeitsverzeichnis" zurück, nicht das Skriptverzeichnis.os.path.dirname(sys.argv[0])
undos.path.dirname(__file__)
geben Sie den Pfad zurück, der zum Aufrufen des Skripts verwendet wird. Dieser kann relativ oder sogar leer sein (wenn sich das Skript im cwd befindet). Auch__file__
gibt es nicht , wenn das Skript in IDLE oder PythonWin ausgeführt wird.sys.path[0]
undos.path.abspath(os.path.dirname(sys.argv[0]))
scheinen das Skriptverzeichnis zurückzugeben. Ich bin mir nicht sicher, ob es einen Unterschied zwischen diesen beiden gibt.
Bearbeiten:
Ich habe gerade festgestellt, dass das, was ich tun möchte, besser als "Öffnen einer Datei im selben Verzeichnis wie das enthaltende Modul" beschrieben werden kann. Mit anderen Worten, wenn ich ein Modul importiere, das ich geschrieben habe und das sich in einem anderen Verzeichnis befindet, und dieses Modul eine Datei öffnet, möchte ich, dass es nach der Datei im Verzeichnis des Moduls sucht. Ich glaube nicht, dass irgendetwas, was ich gefunden habe, dazu in der Lage ist ...
__file__
nicht verwendet werden kann, verwenden Siesys.argv[0]
anstelle vondirname(__file__)
. Der Rest sollte wie erwartet funktionieren. Ich verwende es gerne,__file__
weil es im Bibliothekscodesys.argv[0]
möglicherweise überhaupt nicht auf Ihren Code verweist, insbesondere wenn es über ein Skript eines Drittanbieters importiert wird.realpath( join( getcwd(), dirname(__file__) ))
wie hier beschrieben behandelt wird?So zitieren Sie aus der Python-Dokumentation:
sys.path [0] ist das, wonach Sie suchen.
quelle
os.path.join(sys.path[0], 'some file.txt')
. Das sollte Leerzeichen und Schrägstriche auf allen Systemen korrekt behandeln.Ok hier ist was ich mache
sys.argv ist immer das, was Sie in das Terminal eingeben oder als Dateipfad verwenden, wenn Sie es mit python.exe oder pythonw.exe ausführen
Sie können die Datei text.py beispielsweise auf verschiedene Arten ausführen. Sie geben Ihnen jeweils eine andere Antwort. Sie geben Ihnen immer den Pfad, in den Python eingegeben wurde.
Ok, wissen Sie also, dass Sie den Dateinamen erhalten können, eine große Sache. Um das Anwendungsverzeichnis zu erhalten, können Sie os.path verwenden, insbesondere abspath und dirname
Das wird dies ausgeben:
Dies wird immer ausgegeben, unabhängig davon, ob Sie python test.py oder python "C: \ Dokumente und Einstellungen \ Admin \ test.py" eingeben.
Das Problem bei der Verwendung von __file__ Betrachten Sie diese beiden Dateien test.py
import_test.py
Ausgabe von "python test.py"
Ausgabe von "python test_import.py"
Wie Sie sehen können , gibt Ihnen file immer die Python-Datei, aus der sie ausgeführt wird, und sys.argv [0] gibt Ihnen die Datei an, die Sie immer vom Interpreter ausgeführt haben. Abhängig von Ihren Bedürfnissen müssen Sie auswählen, welches am besten zu Ihren Bedürfnissen passt.
quelle
__file__
ist angeblich „geben Sie immer den Pfad der aktuellen Datei“, undsys.argv[0]
ist angeblich auf „immer den Pfad des Skripts geben, die den Prozess eingeleitet“. In jedem Fall__file__
liefert die Verwendung des aufgerufenen Skripts immer genaue Ergebnisse.__file__
auf die oberste Ebene des Skripts haben, funktioniert dies wie erwartet.Ich konnte den von dcolish bereitgestellten Code erfolgreich verwenden, da ich ein ähnliches Problem beim Lesen einer bestimmten Textdatei hatte. Die Datei befindet sich nicht im selben CWD wie die Python-Datei.
quelle
Ich würde es so machen:
Der obige Code erstellt mit abspath einen absoluten Pfad zur Datei und entspricht der Verwendung von
normpath(join(os.getcwd(), path))
[das stammt aus den Pydocs]. Anschließend wird überprüft, ob diese Datei tatsächlich vorhanden ist, und sie wird dann mithilfe eines Kontextmanagers geöffnet, sodass Sie nicht daran denken müssen, close für das Dateihandle aufzurufen. IMHO, wenn Sie es so machen, werden Sie auf lange Sicht viel Schmerz sparen.quelle
os.path.abspath
Pfade zu Dateien im selben Ordner wie das Skript nicht aufgelöst werden, wenn sich das Skript nicht im aktuellen Verzeichnis befindet.