Попытка прочитать файл JSON в пакете python - PullRequest
2 голосов
/ 15 марта 2020

Я нахожусь в процессе упаковки пакета python, который я буду называть MyPackage.

Структура пакета:

MyPackage/
    script.py
    data.json

Файл data.json Сжимает кэшированные данные, которые читаются в script.py.

Я выяснил, как включить файлы данных (использование setuptool include_package_data=True, а также включить путь к файлу данных в файл MANIFEST.in), но теперь Когда я устанавливаю этот пакет и импортирую установленный MyPackage (в настоящее время тестируем установку с помощью pip из репозитория github), я получаю исключение FileNotFound (data. json) в сценарии, который использует MyPackage. Тем не менее, я вижу, что файл data.json действительно установлен в Lib/site-packages/MyPackage.

Я что-то здесь делаю глупо, пытаясь прочитать файл json в пакете?

Обратите внимание, что в script.py я пытаюсь прочитать data.json как open('data.json', 'r')

Я что-то напортачил относительно пути к файлу данных?

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

3 голосов
/ 15 марта 2020

Вы ничего не напортачили, доступ к ресурсам пакета немного сложен - в основном потому, что они могут быть упакованы в форматы, в которых ваш. json может, строго говоря, не существовать как фактический файл в системе, где находится ваш пакет. установлены. Правильный способ доступа к вашему файлу данных - это не указание пути к нему (например, "MyPackage/data.json"), а доступ к нему как к ресурсу установленного пакета (например, "MyPackage.data.json"). Различие может показаться pedanti c, но оно может иметь большое значение.

В любом случае, доступ должен быть сделан с помощью встроенного importlib.resources модуля:

import importlib.resources
import json

with importlib.resources.path("MyPackage", "data.json") as data_file:
    data = json.load(data_file)  
# you should be able to access 'data' like a dictionary here

Если вы работаете с версией python ниже 3.7, вам придется установить ее как importlib_resources из pyPI.

0 голосов
/ 15 марта 2020

Я решил проблему, получив «относительный путь» к месту, где находится пакет.

self.data = self.load_data(path=os.path.join(
                os.path.dirname(os.path.abspath(__file__)),
                'data.json'))

load_data просто читает файл данных

Любой конструктивная критика все еще очень приветствуется. Не пытаюсь написать глупый код, если я не могу помочь:)

...