2016-11-04 2 views
8

sagen, dass ich ein Python-Projekt, das wie folgt aufgebaut:-Datei mit relativen Pfad in Python-Projekt Lese

project 
    /data 
     test.csv 
    /package 
     __init__.py 
     module.py 
    main.py 

__init__.py:

from .module import test 

module.py:

import csv 

with open("..data/test.csv") as f: 
    test = [line for line in csv.reader(f)] 

main.py:

import package 

print(package.test) 

Als ich main.py laufen bekomme ich folgende Fehlermeldung:

C:\Users\Patrick\Desktop\project>python main.py 
Traceback (most recent call last): 
    File "main.py", line 1, in <module> 
    import package 
    File "C:\Users\Patrick\Desktop\project\package\__init__.py", line 1, in <module> 
    from .module import test 
    File "C:\Users\Patrick\Desktop\project\package\module.py", line 3, in <module> 
    with open("../data/test.csv") as f: 
FileNotFoundError: [Errno 2] No such file or directory: '../data/test.csv' 

Wenn ich jedoch module.py vom package Verzeichnis betreibe ich keine Fehler bekommen. Es scheint also, dass der relative Pfad, der in open(...) verwendet wird, nur relativ zu dem Ort ist, an dem die Ursprungsdatei ausgeführt wird (d. H. __name__ == "__main__")? Ich möchte keine absoluten Pfade verwenden. Was sind einige Möglichkeiten, damit umzugehen?

+1

Als Randbemerkung, zitiert aus PEP8: _ "Relative Importe für Intra-Paket-Importe werden dringend abgeraten. Verwenden Sie immer den absoluten Paketpfad für alle Importe. "_ Hier,' from package.module import test'. – spectras

Antwort

16

Relative Pfade sind relativ zu current working directory. Wenn du nicht willst, dass dein Weg ist, muss er absolut sein.

Aber es ist ein häufig verwendeter Trick einen absoluten Pfad von den aktuellen Skript zu bauen: Verwenden Sie seine __file__ besondere Eigenschaft:

import csv 
import os.path 

my_path = os.path.abspath(os.path.dirname(__file__)) 
path = os.path.join(my_path, "../data/test.csv") 
with open(path) as f: 
    test = list(csv.reader(f)) 

Hinweis, aus Python 3.4 ist __file__ immer absolute für importierte Module und Sie können fallen der os.path.abspath Teil in diesem Beispiel. Nicht, dass es unbedingt notwendig ist, aber es vermeidet Überraschungen, wenn Sie das aktuelle Arbeitsverzeichnis zu einem bestimmten Zeitpunkt ändern und Ihr Modul mit einem relativen Pfad importiert wurde.