在 python 项目中使用相对路径读取文件

假设我有一个 Python 项目,其结构如下:

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

返回文章页面

from .module import test

返回文章页面

import csv


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

返回文章页面

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(...)中使用的相对路径只是相对于原始文件从哪里运行(即 __name__ == "__main__") ?我不想使用绝对路径。有什么办法可以解决这个问题呢?

211099 次浏览

相对路径是相对于 目前的工作目录的。 如果你不希望你的道路是,它必须是绝对的。

但是,从当前脚本构建绝对路径有一个常用的技巧: 使用它的 __file__特殊属性:

from pathlib import Path


path = Path(__file__).parent / "../data/test.csv"
with path.open() as f:
test = list(csv.reader(f))

这需要 python 3.4 + (对于 Pathlib模块)。

如果仍然需要支持旧版本,可以使用以下命令获得相同的结果:

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

[ 2020 edit: python3.4 + 现在应该成为规范,所以我首先根据 jpyams 的评论移动了 pathlib 版本]

对于 Python 3.4 + :

import csv
from pathlib import Path


base_path = Path(__file__).parent
file_path = (base_path / "../data/test.csv").resolve()


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

我的 Python 版本是 Python 3.5.2,在接受的答案中提出的解决方案对我来说不起作用。我还是被指派了一个错误

FileNotFoundError: [Errno 2] No such file or directory

当我在终端运行 my_script.py的时候。尽管当我从 PyCharm IDE (PyCharm 2018.3.2(Community Edition))中通过 Run/Debug Configuration 运行它时,它工作得很好。

解决方案 :

而不是使用:

my_path = os.path.abspath(os.path.dirname(__file__)) + some_rel_dir_path

正如公认的答案所暗示的那样,我使用了:

my_path = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) + some_rel_dir_path

Explanation: 将 os.path.dirname(__file__)改为 os.path.dirname(os.path.abspath(__file__)) 解决以下问题:

当我们像这样运行我们的脚本: python3 my_script.py the __file__ variable has a just a string value of "my_script.py" without path leading to that particular script. That is why method dirname(__file__) returns an empty string "". That is also the reson why my_path = os.path.abspath(os.path.dirname(__file__)) + some_rel_dir_path is actually the same thing as my_path = some_rel_dir_path. Consequently FileNotFoundError: [Errno 2] No such file or directory is given when trying to use open method because there is no directory like "some_rel_dir_path".

运行 PyCharm IDE 的运行/调试配置脚本之所以能够工作,是因为它运行一个命令 python3 /full/path/to/my_script.py(其中“/full/path/to”由我们在运行/调试配置中的“工作目录”变量中指定) ,而不是像我们在终端上运行它时那样运行的 just python3 my_script.py

希望有用。

试试看

with open(f"{os.path.dirname(sys.argv[0])}/data/test.csv", newline='') as f:

这招对我很管用。

with open('data/test.csv') as f:


 

I was thundered when the following code worked.

import os


for file in os.listdir("../FutureBookList"):
if file.endswith(".adoc"):
filename, file_extension = os.path.splitext(file)
print(filename)
print(file_extension)
continue
else:
continue

所以,我检查了 文件,它说:

在版本3.6中更改: 接受类似路径的对象。

类路径对象 :

表示文件系统路径的对象 不是一个字母,就是..。

我做了一个 再深入挖掘一下和下面的工作:

with open("../FutureBookList/file.txt") as file:
data = file.read()