Чтение файла с использованием относительного пути в проекте python

скажем, у меня есть проект 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(...) только относительно того, откуда запускается исходный файл (i.e __name__ == "__main__")? Я не хочу использовать абсолютные пути. Какие есть способы справиться с этим?

1 ответов


относительные пути, относительно текущий рабочий каталог. Если вы не хотите, чтобы ваш путь был, он должен быть абсолютным.

но есть часто используемый трюк для построения абсолютного пути из текущего скрипта: используйте его __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))

Примечание, из python 3.4,__file__ всегда является абсолютным для импортированных модулей, и вы можете удалить os.path.abspath в этом примере. Это не является строго необходимым, но он избегает сюрпризы Если вы измените текущую рабочую директорию в какой-то момент и ваш модуль был импортирован с использованием относительного пути.