在Python项目中使用相对路径阅读文件[duplicate]

fkvaft9z  于 2023-02-14  发布在  Python
关注(0)|答案(6)|浏览(108)
    • 此问题在此处已有答案**:

open() gives FileNotFoundError / IOError: '[Errno 2] No such file or directory'(8个答案)
两个月前关门了。
截至5天前,社区正在审查是否重新讨论此问题。
假设我有一个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(...)中使用的相对路径只是相对于原始文件正在运行的位置(即__name__ == "__main__")?我不想使用绝对路径。有什么方法可以处理这个问题?

dgtucam1

dgtucam11#

相对路径相对于当前工作目录。如果不希望路径是相对路径,则必须是绝对路径。
但是有一个常用的技巧可以从当前脚本构建一个绝对路径:使用其__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版本移到了第一位]*
y1aodyip

y1aodyip2#

对于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)]
xzv2uavs

xzv2uavs3#

这对我很有效。

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

rseugnpd4#

我的Python版本是Python 3.5.2,在接受的答案中提出的解决方案对我不起作用。
未找到文件错误:[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相同的原因。因此,当尝试使用open方法时,会给出FileNotFoundError: [Errno 2] No such file or directory,因为没有类似于"some_rel_dir_path"的目录。
从PyCharm IDE运行/调试配置运行脚本是有效的,因为它运行命令python3 /full/path/to/my_script.py(其中"/full/path/to "由我们在运行/调试配置的"工作目录"变量中指定),而不是像我们从终端运行它时那样只运行python3 my_script.py

c8ib6hqw

c8ib6hqw5#

试试看

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

l7mqbcuq6#

当下面的代码工作时,我感到很惊讶。

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

相关问题