Рубрики
Без рубрики

Легко загружать файлы данных не Python из пакета Python с ImportLib.Resources

Вы когда-нибудь храняте файлы рядом со своими файлами Python, и хотите прочитать их из строя PITH … Теги с Python.

Вы когда-нибудь храняте файлы вместе со своими файлами Python, и хотите прочитать их из строгого скрипта Python?

Использование Импорт Отлично работает на модулях Python и пакеты, но Импорт Не будет работать на файлах данных без Python, таких как текстовые файлы (включая JSON, HTML, CSV и т. Д.) или двоичные файлы (такие как изображения).

ImportLib.resources vs __file__

Вы можете взломать что-то вместе с __File__ Переменная, которая относится к текущему модулю Python в качестве файла в файловой системе. И многие разработчики делают это.

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

Пример

Чтобы продемонстрировать, давайте экспериментируем с простой текстовым файлом рядом с Python модуль , в Пакет Отказ

Начнем с простого проекта с Поэзия (Не стесняйтесь вместо этого использовать инструмент по вашему выбору, или Читать мою INTRO для установки и использования поэзии .

poetry new --src hello
cd hello
poetry install

В SRC/HELLO. мы можем создать два файла, Greeting.txt и приветствовать Отказ

Greeting.txt :

Hello, {recipient}!

greet.py

"""Tools for greeting others."""

import importlib.resources


def greet(recipient):
    """Greet a recipient."""
    template = importlib.resources.read_text("hello", "greeting.txt")
    return template.format(recipient=recipient)

Теперь вы можете запустить консоль Python с Поэзия бежит python и попробуйте следующее:

>>> from hello import greet
>>> greet.greet("World")
'Hello, World!\n'
>>> greet.greet("Universe")
'Hello, Universe!\n'
>>>

Обратите внимание на звонок в importlib.resources.read_text () Отказ Это то, что читает содержимое указанного файла. Есть другие вкусности, такие как ImportLib.resources.read_Binary () . Посмотреть ImportLib.Resources документы Для дальнейшего объяснения и примеров.

Альтернатива, и почему это не так хорошо

Конечно, это также работает:

import pathlib


def greet2(recipient):
    """Greet a recipient, hackily."""
    template = pathlib.Path(__file__).parent.joinpath("greeting.txt").read_text()
    return template.format(recipient=recipient)

В этой реализации нет позора, но это просто немного более хаки, используя переменную Dunder (двойной подчеркивание), получая родительский каталог и т. Д. Не большая сделка, хотя.

Какова большая сделка заключается в том, что пакеты Python могут быть объединены различными способами. Один из этих способов находится в Zip-файле. Файл Ссылка не будет работать должным образом в таком zip-файле, а ImportLib.Resources будет работать нормально.

Кроме того, ImportLib.Resources Улучшает удобное использование импортного пути. Пусть Python найдет пакет и файл под вопросом; Нет необходимости разрабатывать пути относительно Файл Когда вы загружаете данные из файлов, которые находятся в других пакетах. Другими словами, если вы можете Импорт привет Тогда вы можете ImportLib.resources.read_Text («Hello» ...) Независимо от того, какой сценарий или модуль вы используете в данный момент.

Продолжать разбить

Есть один умный взлом, который я все еще должен упомянуть. Линия в приветствовать () можно было написано:

    template = importlib.resources.read_text(__package__, "greeting.txt")

Разница в том, что вместо того, чтобы явно назвать посылку с «Hello», мы используем переменную Dunder __Package__ Это возвращает имя существующего пакета.

Это, конечно, работает только, если вы пытаетесь загрузить ресурсы из одного и того же пакета, который содержит вызов ImportLib.Resources Отказ Если вы переместите функцию в другой пакет, она не удастся.

Итак, хотя не рекомендуется (явт лучше, чем неявным), по крайней мере, вы знаете об этом варианте.

Backport: ImportLib_Resources

Хотите использовать ImportLib.Resources С более старыми версиями Python, например, 3,5 или 3,6?

К счастью, ImportLib_Resources Пакет существует Отказ

Вы можете Поэзия Добавить ImportLib-ресурсы или PIP Установка ImportLib-ресурсов Затем используйте ImportLib_Resources вместо любого ImportLib.Resources В примерах этой статьи.

Другое чтение

Когда вы разработаете свои модули и пакеты, вы можете найти его полезным, чтобы прочитать мою краткое введение в структуру упаковки/модуля в Python.

Счастливый развивающийся!

Оригинал: “https://dev.to/bowmanjd/easily-load-non-python-data-files-from-a-python-package-2e8g”