2016-11-04 480 views
8

說我有一個結構化的Python項目如下:在Python項目使用相對路徑讀取文件

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) 

當我運行main.py我得到以下錯誤:

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' 

但是,如果我從package目錄我沒有得到任何錯誤,運行module.py。因此,open(...)中使用的相對路徑似乎只與源文件從哪裏運行(即​​)有關?我不想使用絕對路徑。有什麼辦法來解決這個問題?

+1

作爲旁註,引用來自PEP8:_「對包裝內進口的相對進口非常不鼓勵。始終使用所有導入的絕對包路徑。「_這裏,從package.module導入測試。 – spectras

回答

16

相對路徑相對於current working directory。 如果你不想要你的道路,它必須是絕對的。

但有一個經常使用的伎倆,以建立從當前腳本的絕對路徑:利用其__file__特殊屬性:

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)) 

注意,從蟒蛇3.4,__file__始終是絕對的進口模塊,並且你可以滴本例中的os.path.abspath部分。並不是說這是絕對必要的,但是如果您在某個時候更改當前工作目錄並且使用相對路徑導入了模塊,則可以避免意外。

相關問題