Как ссылаться на относительные пути ресурсов при работе с хранилищем кода

Мы работаем с хранилищем кода, которое развернуто как в Windows, так и в Linux - иногда в разных каталогах. Как один из модулей внутри проекта должен ссылаться на один из не-Python ресурсов в проекте (файлы CSV и т.д.)?

Если мы сделаем что-то вроде:

thefile=open('test.csv')

или:

thefile=open('../somedirectory/test.csv')

Он будет работать только тогда, когда скрипт запускается из одного определенного каталога или подмножества каталогов.

Я хотел бы сделать что-то вроде:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

Возможно ли это?

Ответ 1

Попробуйте использовать имя файла относительно текущего пути к файлам. Пример для "./my_file":

fn = os.path.join(os.path.dirname(__file__), 'my_file')

В Python 3. 4+ вы также можете использовать pathlib:

fn = pathlib.Path(__file__).parent / 'my_file'

Ответ 2

Если вы используете инструменты установки или распространяете (установка setup.py), то "правильный" способ доступа к этим упакованным ресурсам, похоже, использует package_resources.

В вашем случае пример будет

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

Что, конечно, читает ресурс, а чтение двоичных данных будет значением my_data​​p >

Если вам просто нужно имя файла, вы также можете использовать

resource_filename(package_or_requirement, resource_name)

Пример:

resource_filename("MyPackage","foo.dat")

Преимущество заключается в том, что он гарантированно работает, даже если это распределение архива, такое как яйцо.

См. http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api

Ответ 3

В Python пути относятся к текущему рабочему каталогу , который в большинстве случаев является каталогом, из которого вы запускаете свою программу. Текущий рабочий каталог, скорее всего, не такой же, как каталог вашего файла модуля, поэтому использование пути относительно вашего текущего файла модуля всегда является плохим выбором.

Использование абсолютного пути должно быть лучшим решением:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')

Ответ 4

Я часто использую что-то похожее на это:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

Переменная

__file__

содержит имя файла script, в котором вы записываете этот код, поэтому вы можете создавать пути относительно script, но все же записываться с абсолютными путями. Он работает достаточно хорошо по нескольким причинам:

  • путь является абсолютным, но все же относительным
  • проект все еще может быть развернут в относительном контейнере

Но вам нужно следить за совместимостью с платформой - os.pathsep для Windows отличается от UNIX.

Ответ 5

import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

Вы также пытаетесь нормализовать свой cwd с помощью os.path.abspath(os.getcwd()). Больше информации здесь.

Ответ 6

Вы можете использовать встроенную переменную __file__. Он содержит путь к текущему файлу. Я бы использовал getBaseOfProject в модуле в корне вашего проекта. Там я бы получил часть пути __file__ и вернул бы это. Этот метод можно использовать везде в вашем проекте.

Ответ 7

Я немного озадачен здесь. Хотел упаковать некоторые файлы ресурсов в файл wheel и получить к ним доступ. Выполнял упаковку, используя файл манифеста, но pip install не устанавливал его, если он не был подкаталогом. Надеемся, что эти снимки помогут

├── cnn_client
│   ├── image_preprocessor.py
│   ├── __init__.py
│   ├── resources
│   │   ├── mscoco_complete_label_map.pbtxt
│   │   ├── retinanet_complete_label_map.pbtxt
│   │   └── retinanet_label_map.py
│   ├── tf_client.py

MANIFEST.in

recursive-include cnn_client/resources *

Создал weel используя стандартный setup.py. Пип установил файл колеса. После установки проверил, установлены ли ресурсы. Они есть

ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt 
 retinanet_label_map.py  

В tfclient.py для доступа к этим файлам. от

templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
 file_path = os.path.join(templates_dir, \
            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()

И это работает.

Ответ 8

Может ли кто-нибудь тело сказать мне, как я могу установить свой путь к каталогу в файл конфигурации ymal.

Я попробовал следующий способ:

file_path: 'os.path.abspath (путь (файл).absolute(). parent, "NAD_Status_Report _ {} _ {}. csv")'

Ответ 9

Я долгое время выяснял ответ на этот вопрос, но я, наконец, получил его (и это действительно очень просто):

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

Это добавит относительный путь вашей подпапки к каталогам для python, чтобы посмотреть в Это довольно быстро и грязно, но это работает как шарм:)