Öffnen Sie die Datei an einem relativen Speicherort in Python


132

Angenommen, Python-Code wird in einem früheren Windows-Verzeichnis ausgeführt, das nicht bekannt ist, z. B. 'main', und überall dort, wo Code bei der Ausführung installiert wird, muss auf das Verzeichnis 'main / 2091 / data.txt' zugegriffen werden.

Wie soll ich die Funktion open (location) verwenden? Was soll Standort sein?

Bearbeiten:

Ich fand, dass unten einfacher Code funktioniert. Hat er irgendwelche Nachteile?

    file="\2091\sample.txt"
    path=os.getcwd()+file
    fp=open(path,'r+');

1
Sie verwenden ungekapselte Backslashes. Das ist ein Nachteil.
Orip

6
Mehrere Nachteile. 1) Verwenden Sie gemäß @orip Schrägstriche für Pfade, auch unter Windows. Ihre Zeichenfolge funktioniert nicht. Oder verwenden Sie rohe Zeichenfolgen wie r"\2091\sample.txt". Oder entkomme ihnen wie "\\2091\\sample.txt"(aber das ist nervig). Außerdem verwenden Sie 2) getcwd (), den Pfad, in dem Sie sich beim Ausführen des Skripts befanden. Ich dachte, Sie wollten relativ zum Speicherort des Skripts (aber jetzt wundere ich mich). Und 3) verwenden Sie immer os.pathFunktionen zum Bearbeiten von Pfaden. Ihre Verbindungslinie sollte os.path.join(os.getcwd(), file)4) die sein; ist sinnlos
Russ

3
Und für ein gutes Maß ... 5) Verwenden Sie Kontextschutz, um es sauber zu halten und nicht zu vergessen, Ihre Datei zu schließen : with open(path, 'r+') as fp:. Sehen Sie hier für die beste Erklärung von withAussagen die ich gesehen habe.
Russ

Neben der notwendigen Sorgfalt bei Schrägstrichen, wie gerade angegeben, gibt es die Funktion os.path.abspath, einfach den vollständigen Pfad des relativen Pfads zu öffnen. Die endgültige Aussage sieht folgendermaßen aus:os.path.abspath('./2091/sample.txt')
OPMendeavour

Antworten:


189

Bei dieser Art von Dingen müssen Sie vorsichtig sein, was Ihr tatsächliches Arbeitsverzeichnis ist. Beispielsweise können Sie das Skript möglicherweise nicht in dem Verzeichnis ausführen, in dem sich die Datei befindet. In diesem Fall können Sie nicht einfach einen relativen Pfad selbst verwenden.

Wenn Sie sicher sind, dass sich die gewünschte Datei in einem Unterverzeichnis befindet, unter dem sich das Skript tatsächlich befindet, können __file__Sie hier helfen. __file__ist der vollständige Pfad zu dem Skript, das Sie ausführen.

Sie können also mit so etwas herumspielen:

import os
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

Ich fand, dass unten einfacher Code funktioniert. Hat er irgendwelche Nachteile? <pre> file = "\ sample.txt" path = os.getcwd () + str (loc) + file fp = open (Pfad, 'r +'); <code>

@Arash Der Nachteil dabei ist, dass cwd (aktuelles Arbeitsverzeichnis) alles sein kann und nicht unbedingt dort sein muss, wo sich Ihr Skript befindet.
Cory Mawhorter

5
__file__ist ein relativer Pfad (zumindest in meinem Setup aus irgendeinem Grund), und Sie müssen os.path.abspath(__file__)zuerst aufrufen . Osx / Homebrew 2.7
Cory Mawhorter

2
os.path.dirname ( Datei ) funktioniert in Python 2.7 nicht für mich. Es zeigtNameError: name '__file__' is not defined
Soumendra

1
@ Soumendra Ich denke du versuchst es in der Konsole. Versuchen Sie es in einer * .py-Datei.
Enku

35

Dieser Code funktioniert gut:

import os


def readFile(filename):
    filehandle = open(filename)
    print filehandle.read()
    filehandle.close()



fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir

#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)

#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)

#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)

#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)

Für mich hat der Zugriff auf die Datei im übergeordneten Ordner des aktuellen Ordners nicht funktioniert. Das .. wird als Zeichenfolge hinzugefügt.
M. Paul

Funktionierte nicht unter Windows. Der Pfad zur Datei ist korrekt, aber Python gibt "Datei nicht gefunden" an und zeigt den Pfad mit \\ Trennzeichen an.
Lonstar

26

Ich habe ein Konto erstellt, um eine Diskrepanz zu klären, die ich in Russ 'ursprünglicher Antwort gefunden habe.

Als Referenz war seine ursprüngliche Antwort:

import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

Dies ist eine großartige Antwort, da versucht wird, dynamisch einen absoluten Systempfad zur gewünschten Datei zu erstellen.

Cory Mawhorter bemerkte, dass dies __file__ein relativer Pfad ist (dies gilt auch für mein System) und schlug vor, ihn zu verwenden os.path.abspath(__file__). os.path.abspathGibt jedoch den absoluten Pfad Ihres aktuellen Skripts zurück (dh /path/to/dir/foobar.py)

Um diese Methode zu verwenden (und wie ich sie schließlich zum Laufen gebracht habe), müssen Sie den Skriptnamen am Ende des Pfads entfernen:

import os
script_path = os.path.abspath(__file__) # i.e. /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] #i.e. /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

Der resultierende abs_file_path (in diesem Beispiel) wird zu: /path/to/dir/2091/data.txt


14
Sie könnten sogar beide Ansätze für die einfachere kombinierenos.path.dirname(os.path.abspath(__file__))
Luke Taylor

1
@LukeTaylor In der Tat wäre das besser, als zu versuchen, die os.path.dirnameFunktionalität selbst zu replizieren, wie ich es in meiner Antwort im letzten Jahr getan habe.
Grant Hulegaard

19

Dies hängt davon ab, welches Betriebssystem Sie verwenden. Wenn Sie eine Lösung suchen, die sowohl mit Windows als auch mit * nix kompatibel ist, können Sie Folgendes tun:

from os import path

file_path = path.relpath("2091/data.txt")
with open(file_path) as f:
    <do stuff>

sollte gut funktionieren.

Das pathModul kann einen Pfad für jedes Betriebssystem formatieren, auf dem es ausgeführt wird. Außerdem verarbeitet Python relative Pfade einwandfrei, sofern Sie über die richtigen Berechtigungen verfügen.

Bearbeiten :

Wie von kindall in den Kommentaren erwähnt, kann Python ohnehin zwischen Pfaden im Unix- und Windows-Stil konvertieren, sodass noch einfacherer Code funktioniert:

with open("2091/data/txt") as f:
    <do stuff>

Trotzdem hat das pathModul noch einige nützliche Funktionen.


3
relpath()konvertiert einen Pfadnamen in einen relativen Pfad. Da es bereits ein relativer Pfad ist, wird es nichts tun.
Kindall

Gegebenenfalls wird es von einem Pfad im Unix-Stil in einen Pfad im Windows-Stil konvertiert. Gibt es eine andere Funktion im os.pathModul, die die bessere Wahl wäre?
Wilduck

1
Windows funktioniert bereits mit einem UNIX-Pfad. Zumindest die NT-basierte Serie wird (2000, XP, Vista, 7). Es ist keine Konvertierung erforderlich.
Kindall

7
Diese Antwort ist nicht ganz richtig und wird Probleme verursachen. Relative Pfade beziehen sich standardmäßig auf das aktuelle Arbeitsverzeichnis (Pfad, von dem aus das Skript ausgeführt wurde) und NICHT auf den tatsächlichen Speicherort des Skripts. Sie müssen verwenden __file__. Bitte sehen Sie meine Antwort.
Russ

Hat der Autor dieser Antwort os.path.relpath mit os.path.abspath verwechselt?
Foobarbecue

15

Ich verbringe viel Zeit damit, herauszufinden, warum mein Code meine Datei mit Python 3 auf dem Windows-System nicht finden konnte. Also habe ich hinzugefügt. vorher / und alles hat gut funktioniert:

import os

script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')

Besser:file_path = os.path.join(script_dir, 'output03.txt')
Mr_and_Mrs_D

Ich habe das unter Windows versucht, aber ich hatte keinen Erfolg.
Angelo Polotto

Interessant - können Sie script_dir drucken? Dann drehen Sie es auf absoluten Pfad wie inscript_dir = os.path.abspath(os.path.dirname(__file__))
Mr_and_Mrs_D

Ich werde das versuchen, wenn es mir gelingt, werde ich die Antwort ändern.
Angelo Polotto

6

Code:

import os
script_path = os.path.abspath(__file__) 
path_list = script_path.split(os.sep)
script_directory = path_list[0:len(path_list)-1]
rel_path = "main/2091/data.txt"
path = "/".join(script_directory) + "/" + rel_path

Erläuterung:

Bibliothek importieren:

import os

Verwenden Sie __file__diese Option, um den Pfad des aktuellen Skripts zu ermitteln:

script_path = os.path.abspath(__file__)

Trennt den Skriptpfad in mehrere Elemente:

path_list = script_path.split(os.sep)

Entfernen Sie das letzte Element in der Liste (die eigentliche Skriptdatei):

script_directory = path_list[0:len(path_list)-1]

Fügen Sie den Pfad der relativen Datei hinzu:

rel_path = "main/2091/data.txt

Verbinden Sie die Listenelemente und fügen Sie die Datei des relativen Pfads hinzu:

path = "/".join(script_directory) + "/" + rel_path

Jetzt können Sie mit der Datei tun, was Sie wollen, wie zum Beispiel:

file = open(path)

Stattdessen path = "/".join(script_directory) + "/" + rel_pathsollten Sie das OS-Modul wie in verwenden path = os.path.join(script_directory, rel_path). Anstatt den Pfad, den Sie verwenden sollten, manuell zu analysierenscript_path = os.path.dirname(__file__)
Mr_and_Mrs_D

3

Wenn sich die Datei in Ihrem übergeordneten Ordner befindet, z. follower.txt können Sie einfach verwendenopen('../follower.txt', 'r').read()


3

Versuche dies:

from pathlib import Path

data_folder = Path("/relative/path")
file_to_open = data_folder / "file.pdf"

f = open(file_to_open)

print(f.read())

Mit Python 3.4 wurde eine neue Standardbibliothek für den Umgang mit Dateien und Pfaden namens pathlib eingeführt. Für mich geht das!


2

Ich bin mir nicht sicher, ob das überall funktioniert.

Ich benutze Ipython in Ubuntu.

Wenn Sie die Datei im Unterverzeichnis des aktuellen Ordners lesen möchten:

/current-folder/sub-directory/data.csv

Ihr Skript befindet sich im aktuellen Ordner. Versuchen Sie einfach Folgendes:

import pandas as pd
path = './sub-directory/data.csv'
pd.read_csv(path)

1

Python übergibt nur den Dateinamen, den Sie ihm geben, an das Betriebssystem, wodurch es geöffnet wird. Wenn Ihr Betriebssystem relative Pfade wie main/2091/data.txt(Hinweis: es tut) unterstützt, funktioniert das einwandfrei.

Möglicherweise können Sie eine solche Frage am einfachsten beantworten, indem Sie sie ausprobieren und sehen, was passiert.


2
Nicht wahr ... Das Arbeitsverzeichnis in einem Skript ist der Speicherort, von dem aus Sie das Skript ausgeführt haben, nicht der Speicherort des Skripts. Wenn Sie das Skript von einer anderen Stelle aus ausführen (möglicherweise befindet sich das Skript in Ihrem Systempfad), funktioniert der relative Pfad zum Unterverzeichnis nicht. Bitte lesen Sie meine Antwort, wie Sie das umgehen können.
Russ

@Russ - das Beispiel des OP verwendet getcwd(). Ich habe die ursprüngliche Beschreibung als "relativ zu dem Ort, an dem ich das Skript ausführe, unabhängig davon, wo sich der Code befindet" gelesen.
Orip

@orip - Das OP hat den Aufruf getcwd () 3 Stunden nach der Frage hinzugefügt. Egal ... weiter. :)
Russ

1
import os
def file_path(relative_path):
    dir = os.path.dirname(os.path.abspath(__file__))
    split_path = relative_path.split("/")
    new_path = os.path.join(dir, *split_path)
    return new_path

with open(file_path("2091/data.txt"), "w") as f:
    f.write("Powerful you have become.")

0

Als Anfänger fand ich diese Beschreibungen etwas einschüchternd. Wie zuerst würde ich es versuchen For Windows

f= open('C:\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f) 

und dies würde eine erhöhen syntax error. Ich war oft verwirrt. Dann nach einigem Surfen über Google. gefunden, warum der Fehler aufgetreten ist. Schreiben Sie dies für Anfänger

Damit der Pfad in Unicode gelesen werden kann, fügen Sie \beim Starten des Dateipfads einfach einen hinzu

f= open('C:\\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)

Und jetzt funktioniert es einfach hinzufügen, \bevor Sie das Verzeichnis starten.


1
Backslashes sind Escape-Zeichen für mehrere Zeichen. Wenn Sie Begegnung passieren , \twie zum Beispiel \top\directory, als ‚\ t‘ wird als Tab-Zeichen interpretiert und Ihr ‚Trick‘ schlägt fehl. Die beste Option ist die Verwendung des rohen Zeichenfolgenformats, bei r'C:\Users\chidu\Desktop\Skipper New\Special_Note.txt'dem nicht versucht wird, Zeichen zu maskieren.
Ronald
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.