Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python项目中使用相对路径读取文件_Python_Python 3.x_Io_Relative Path_Python Import - Fatal编程技术网

在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

假设我有一个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.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。