Relative Pfadangaben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Hallo Leute,

ich habe eine recht einfache Frage:

Ich habe etwa Folgenden Quellcode:

Code: Alles auswählen


test = "datei.txt"
with open(test) as datei:
      for line in datei:
            print line

Das Problem ist: Im Moment muss die Datei datei.txt im gleichen Verzeichnis liegen wie das Script. Ich möchte jetzt die Datei datei.txt in ein anderes Verzeichnis verschieben und in meinem Script dann relativ darauf zugreifen etwa so: \..\folder1\datei.txt

Wie funktioniert das?

Danke im Voraus!

Killigen
BlackJack

@Killigen: Der Name `__file__` ist in jedem Modul definiert und enthält den Pfad/Dateinamen des Moduls. Davon ausgehend kann man sich mit den Funktionen in `os.path` (`dirname()`, `join()`) den passenden Pfad zusammenstellen.
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Ist mir nicht ganz klar wie du das meinst... Könntest du evtl. einen Beispielcode posten?

Mir ist klar dass ich mit __file__ den absoluten Pfad des Scripts bekomme aber ich möchte von diesem Verzeichnis quasi \..\ machen also ein Verzeichnis nach oben und von dort aus wieder in einen anderen Ordner springen ohne konkrete also absolute Verzeichnisse anzugeben. Könntest du dafür bitte Beispielcode posten?
Zuletzt geändert von Killigen am Montag 27. April 2015, 11:26, insgesamt 1-mal geändert.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Killigen hat geschrieben:Im Moment muss die Datei datei.txt im gleichen Verzeichnis liegen wie das Script. Ich möchte jetzt die Datei datei.txt in ein anderes Verzeichnis verschieben und in meinem Script dann relativ darauf zugreifen etwa so: \..\folder1\datei.txt
Ganz simpel geht das einfach so

Code: Alles auswählen

test = "../folder1/datei.txt"
with open(test) as datei:
      for line in datei:
            print line
Auch unter Windows, kannst Du in Python für Pfadangaben "/" benutzen.

Wenn Du es ein bisschen komplizierter mit __file__ brauchst, dann findest Du in diesem Thread Infos dazu: http://www.python-forum.de/viewtopic.php?f=24&t=36126
a fool with a tool is still a fool, www.magben.de, YouTube
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

@MagBen: Habe deinen Vorschlag ausprobiert. Leider kommt hier: No such file or directory: '../folder2/datei.txt'
Die Datei ist aber sehr wohl vorhanden...
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Dann mach mal die folgende Debugausgabe in Deinem Skript:

Code: Alles auswählen

import os
print( os.path.abspath("../folder2"))
und schaue mit dem Dateiexplorer dort nach.
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Wenn die Datei vorhanden wäre, würde die Fehlermeldung nicht kommen ;)

Wie genau sieht denn deine Ordnerstruktur aus?
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

@sparrow: Auf wie Idee wäre ich auch schon gekommen :D aber sie ist vorhanden... Ich habe einen Ordner folder1 in dem befindet sich das Skript. Außerdem habe ich einen Ordner folder2 in dem ist die txt-datei beide Ordner also folder1 und folder2 befinden sich im selben Verzeichnis...

@MagBen: Ich bin nicht ganz sicher was du meinst... Also wenn ich genau deinen Code so übernehme und nur den ausführe bekomme ich das: C:\LegacyApp\folder2 allerdings ist der Ordner eigentlich auf dem Desktop!?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Killigen hat geschrieben: Ich bin nicht ganz sicher was du meinst... Also wenn ich genau deinen Code so übernehme und nur den ausführe bekomme ich das: C:\LegacyApp\folder2 allerdings ist der Ordner eigentlich auf dem Desktop!?
Mit einer relativen Pfadangabe suchst Du die Datei relativ zum aktuellen Arbeitsverzeichnis. Wenn dann die Datei nicht gefunden wird, obwohl sie eigentlich da sein müsste, dann liegt das oftmals daran, dass das aktuelle Arbeitsverzeichnis nicht so wie gedacht ist. Deshalb ist dieser Test wohl besser als mein erster Vorschlag:

Code: Alles auswählen

import os
print( os.path.abspath("."))
a fool with a tool is still a fool, www.magben.de, YouTube
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Ok! Mit der Anweisung bekomme ich jetzt den Pfad der Datei... Soweit so gut... Wenn ich jetzt aber sowas mache:

Code: Alles auswählen

test = "C:\Users\xyz\Desktop\Test\folder1"

with open(test) as datei:
      for line in datei:
            print line
Dann funktioniert das nicht...!?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Probier mal das

Code: Alles auswählen

test = r"C:\Users\xyz\Desktop\Test\folder1"
oder das

Code: Alles auswählen

test = "C:/Users/xyz/Desktop/Test/folder1"
a fool with a tool is still a fool, www.magben.de, YouTube
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Jetzt mache ich Folgendes:

Code: Alles auswählen

import os
test = os.path.abspath("..")

test = test + "\\folder2"

test = test.replace("\\","/")

with open(test) as datei:
    for line in datei:
        print line
Ich starte quasi im Verzeichnis meines Skripts gehe eins nach oben und dann wieder eins nach unten... Dann mach ich ein replace...

Jetzt bekomme ich allerdings folgenden Fehler:

IOError: [Errno 13] Permission denied: 'C:/Users/xyz/Desktop/Test/folder2'

WTF? :D
BlackJack

@Killigen: Du startest nur dann im Verzeichnis Deines Skripts wenn das Arbeitsverzeichnis des Aufrufers da gerade ist.

Bitte verwende die entsprechenden Funktionen aus dem `os.path`-Modul um Pfade und Pfadteile zu verarbeiten und keine ``+`` und `replace()`-Operationen auf Zeichenketten.

Zur Ausnahme: Du versuchst ``C:/Users/xyz/Desktop/Test/folder2`` als *Datei* zu öffnen, und das ist nicht erlaubt. Was sollte das auch für eine Datei sein?
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

@BlackJack: Ok das ist wirklich ein Fehler... Ich habe den Dateinamen vergessen anzugeben :D aber warum kann ich hier nicht mit replace() und + arbeiten? Die Variable ist ja vom Typ String...!? Und wenn... was sind die entsprechenden funktionen aus dem "os-path"-Modul? Könntest du mir evtl. den Code so umschreiben wie du ihn dir "richtig" vorstellst?
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Killigen: wofür gibt es eine Dokumentation? Da sind auch genug Beispiele für os.path.join drin. Und warum sollte man denn die richtigen Pfadtrenner mit replace durch falsche ersetzen wollen???
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Killigen hat geschrieben:[...] warum kann ich hier nicht mit replace() und + arbeiten? Die Variable ist ja vom Typ String...!?
Semantisch sind das Pfade im Dateisystem und die sollte man dann auch mit den entsprechenden Funktionen bearbeiten. Damit bist du unabhängig vom System auf dem das Programm läuft.

Lass mal folgenden Code laufen und versuche die Ergebnisse zu verstehen (print hat Klammern, da ich mit Python 3 arbeite).

Code: Alles auswählen

import os

def main():
    print(__file__)
    print(os.path.dirname(__file__))
    print(os.path.join(os.path.dirname(__file__), '..', 'folder2'))
    print(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'folder2')))


if __name__ == '__main__':
    main()
Antworten