在python项目中使用相对路径读取文件
假设我有一个python项目,其结构如下:在python项目中使用相对路径读取文件,python,python-3.x,io,relative-path,python-import,Python,Python 3.x,Io,Relative Path,Python Import,假设我有一个python项目,其结构如下: project /data test.csv /package __init__.py module.py main.py \uuuu init\uuuuu.py: from .module import test import csv with open("..data/test.csv") as f: test = [line for line in csv.re
project
/data
test.csv
/package
__init__.py
module.py
main.py
\uuuu init\uuuuu.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)
module.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
:
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'
C:\Users\Patrick\Desktop\project>python main.py
回溯(最近一次呼叫最后一次):
文件“main.py”,第1行,在
进口包装
文件“C:\Users\Patrick\Desktop\project\package\\uuuuu init\uuuuuu.py”,第1行,在
模块导入测试
文件“C:\Users\Patrick\Desktop\project\package\module.py”,第3行,在
将open(“../data/test.csv”)作为f:
FileNotFoundError:[Errno 2]没有这样的文件或目录:'../data/test.csv'
但是,如果从
包
目录运行module.py
,则不会出现错误。因此,open(…)
中使用的相对路径似乎仅与原始文件的运行位置相关(即\uuuuuuu name\uuuuuuu==“\uuuuu main\uuuuu”
)?我不想使用绝对路径。有哪些方法可以解决这个问题?相对路径是相对的。
如果你不想你的道路是,它必须是绝对的
但从当前脚本构建绝对路径有一个常用技巧:使用其特殊属性:
from pathlib import Path
path = Path(__file__).parent / "../data/test.csv"
with path.open() as f:
test = list(csv.reader(f))
这需要Python3.4+(用于模块)
如果您仍然需要支持旧版本,您可以通过以下方式获得相同的结果:
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版本]用于Python 3.4+:
导入csv
从pathlib导入路径
基本路径=路径(文件)。父
文件路径=(基本路径/“./data/test.csv”).resolve()
打开(文件路径)为f时:
test=[csv.reader中的行对行(f)]
我的Python版本是Python3.5.2,在接受的答案中提出的解决方案对我不起作用。我仍然被给了一个错误
FileNotFoundError: [Errno 2] No such file or directory
当我从终端运行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(\uu文件\uu)更改为os.path.dirname(os.path.abspath(\uu文件\uu))
解决以下问题:
当我们这样运行脚本时:python3 my_script.py
\uuuuu file\uuuu
变量只有一个字符串值“my\u script.py”,没有指向该特定脚本的路径。这就是为什么方法dirname(\uuuu file\uuuu)
返回一个空字符串“”。这也是为什么my\u path=os.path.abspath(os.path.dirname(\uuu file\uuu))+some\u rel\u dir\u path
实际上与my\u path=some\u rel\u dir\u path
相同的原因。因此,FileNotFoundError:[Errno 2]在尝试使用open
方法时,不会给出这样的文件或目录,因为没有类似“some\u rel\u dir\u path”的目录
从PyCharm IDE运行/调试配置运行脚本之所以有效,是因为它运行的是命令python3/full/path/to/my_script.py
(其中“/full/path/to”由我们在运行/调试配置中的“Working directory”变量中指定)而不是像从终端运行python3 my_script.py那样只执行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:
当下面的代码运行时,我大吃一惊
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()
作为旁注,引用PEP8的话:“对于包内导入,不鼓励使用相对导入。对于所有导入,始终使用绝对包路径。”这里,来自package.module import test
。当然,如果您使用的是Python 3.4+,您可以只使用:路径(u文件)。parent.resolve()
,这确实是一个警告。显式运行脚本是非常罕见的,您似乎是第一个注意到的(通常您会将#!/usr/bin/env python
放在顶部,将其标记为可执行,并将其作为/myscript.py
运行)。pathlib.Path的pathlib.Path版本没有这个gotcha,尽管这可能是一个更好的选项,因为python3.4.Oh是的。这正是我在任务中所缺少的。非常感谢@programmer。