在 Python 项目中使用相对路径读取文件
- 2025-01-14 08:50:00
- admin 原创
- 115
问题描述:
假设我有一个 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:UsersPatrickDesktopproject>python main.py
Traceback (most recent call last):
File "main.py", line 1, in <module>
import package
File "C:UsersPatrickDesktopprojectpackage__init__.py", line 1, in <module>
from .module import test
File "C:UsersPatrickDesktopprojectpackagemodule.py", line 3, in <module>
with open("../data/test.csv") as f:
FileNotFoundError: [Errno 2] No such file or directory: '../data/test.csv'
但是,如果我module.py
从package
目录运行,则不会出现任何错误。因此,似乎 中使用的相对路径open(...)
仅相对于原始文件的运行位置(即__name__ == "__main__"
)?如何处理这个问题,仅使用相对路径?
解决方案 1:
相对路径是相对于当前工作目录的。如果你不想使用相对路径,则必须是绝对路径。
但是有一个经常使用的技巧可以从当前脚本构建绝对路径:使用它的__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 年编辑: python3.4+ 现在应该是常态,因此我首先移动了受 jpyams 评论启发的 pathlib 版本]
解决方案 2:
对于 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)]
解决方案 3:
这对我有用。
with open('data/test.csv') as f:
解决方案 4:
我的 Python 版本是Python 3.5.2,接受的答案中提出的解决方案对我不起作用。我仍然收到错误
FileNotFoundError:[Errno 2] 没有这样的文件或目录
my_script.py
当我从终端运行时。虽然当我通过PyCharm IDE(PyCharm 2018.3.2(社区版))的运行/调试配置运行它时,它工作正常。
解决方案:
而不是使用:
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
解释:
更改os.path.dirname(__file__)
为os.path.dirname(os.path.abspath(__file__))
可解决以下问题:
当我们像这样运行脚本时:python3 my_script.py
变量__file__
只有一个字符串值“my_script.py”,而没有指向该特定脚本的路径。这就是方法dirname(__file__)
返回空字符串“”的原因。这也是为什么my_path = os.path.abspath(os.path.dirname(__file__)) + some_rel_dir_path
实际上与相同的原因my_path = some_rel_dir_path
。因此,FileNotFoundError: [Errno 2] No such file or directory
当尝试使用open
方法时会给出结果,因为没有像“some_rel_dir_path”这样的目录。
从 PyCharm IDE 运行/调试配置运行脚本之所以有效,是因为它运行一个命令python3 /full/path/to/my_script.py
(其中“/full/path/to”由我们在运行/调试配置中的“工作目录”变量中指定),而不是像python3 my_script.py
我们从终端运行它时那样。
解决方案 5:
尝试
with open(f"{os.path.dirname(sys.argv[0])}/data/test.csv", newline='') as f:
解决方案 6:
当下面的代码起作用时我感到很惊讶。
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 版更改: 接受类似路径的对象。
路径类对象:
表示文件系统路径的对象。路径类对象可以是 str 或...
我做了一些进一步的挖掘,以下内容也有效:
with open("../FutureBookList/file.txt") as file:
data = file.read()