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

pbr*_*ach 45 python io relative-path python-import python-3.x

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

project
    /data
        test.csv
    /package
        __init__.py
        module.py
    main.py
Run Code Online (Sandbox Code Playgroud)

__init__.py:

from .module import test
Run Code Online (Sandbox Code Playgroud)

module.py:

import csv

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

main.py:

import package

print(package.test)
Run Code Online (Sandbox Code Playgroud)

当我运行时,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'
Run Code Online (Sandbox Code Playgroud)

但是,如果我module.pypackage目录运行,我没有错误.所以看起来使用的相对路径open(...)只相对于原始文件的运行位置(即__name__ == "__main__")?我不想使用绝对路径.有什么方法可以解决这个问题?

spe*_*ras 64

相对路径相对于当前工作目录.如果你不想要自己的道路,那一定是绝对的.

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

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))
Run Code Online (Sandbox Code Playgroud)

请注意,从python 3.4开始,__file__对于导入的模块始终是绝对的,您可以os.path.abspath在此示例中删除该部分.并不是说它是绝对必要的,但如果你在某个时候改变当前的工作目录并且使用相对路径导入模块,它可以避免意外.

  • 当然,如果你使用的是Python 3.4+,你可以使用[pathlib.Path](https://docs.python.org/3/library/pathlib.html):`Path(__ file __).parent.resolve ()` (11认同)

aks*_*618 11

对于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)]
Run Code Online (Sandbox Code Playgroud)


pro*_*mer 6

这对我有用。

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

 
Run Code Online (Sandbox Code Playgroud)

  • 事实上,这根本不是问题的答案,因为OP特别询问了一个可以从任何地方运行而不仅仅是从特定文件夹运行的解决方案。 (2认同)