Управление ресурсами в проекте Python
-
22-09-2019 - |
Вопрос
У меня есть проект Python, в котором я использую множество не-кодных файлов. В настоящее время это все изображения, но я мог бы использовать другие виды файлов в будущем. Что будет хорошей схемой для хранения и ссылки на эти файлы?
Я рассматривал просто создание папки «ресурсы» в главном каталоге, но есть проблема; Некоторые изображения используются из подпакнов моего проекта. Хранение этих изображений таким образом приведет к связке, что является недостатком.
Кроме того, мне нужен способ получить доступ к этим файлам, который не зависит от моего текущего каталога.
Решение
Вы можете использовать pkg_resources
библиотека, которая идет с setuptools
.
Например, я составил быстрый маленький пакет "proj"
Чтобы проиллюстрировать схему организации ресурсов, я бы использовал:
proj/setup.py proj/proj/__init__.py proj/proj/code.py proj/proj/resources/__init__.py proj/proj/resources/images/__init__.py proj/proj/resources/images/pic1.png proj/proj/resources/images/pic2.png
Обратите внимание, как я держу все ресурсы в отдельном подпакете.
"code.py"
покажи покажи pkg_resources
используется для обозначения объектов ресурса:
from pkg_resources import resource_string, resource_listdir
# Itemize data files under proj/resources/images:
print resource_listdir('proj.resources.images', '')
# Get the data file bytes:
print resource_string('proj.resources.images', 'pic2.png').encode('base64')
Если вы запустите его, вы получите:
['__init__.py', '__init__.pyc', 'pic1.png', 'pic2.png'] iVBORw0KGgoAAAANSUhE ...
Если вам нужно рассматривать ресурс как к файловому делу, используйте resource_stream()
.
Доступ к коду, доступа к ресурсам, может быть где угодно в рамках структуры подпакета вашего проекта, ему просто необходимо обратиться к подпакету, содержащему изображения по полному имени: proj.resources.images
, в таком случае.
Вот "setup.py"
:
#!/usr/bin/env python
from setuptools import setup, find_packages
setup(name='proj',
packages=find_packages(),
package_data={'': ['*.png']})
Предостережение:Чтобы проверить вещи «локально», то есть без установки пакета сначала, вам придется вызвать свои тестовые сценарии из каталога, который имеет setup.py
. Анкет Если вы находитесь в том же каталоге, что и code.py
, Python не узнает о proj
упаковка. Так что вещи вроде proj.resources
не решается.
Другие советы
Вы всегда можете иметь отдельную папку «ресурсы» в каждом подпакете, которая в ней нуждается, и использовать os.path
функции, чтобы добраться до них из __file__
Значения ваших подпакеров. Чтобы проиллюстрировать, что я имею в виду, я создал следующее __init__.py
Файл в трех местах:
c:\temp\topp (top-level package) c:\temp\topp\sub1 (subpackage 1) c:\temp\topp\sub2 (subpackage 2)
Вот __init__.py
файл:
import os.path
resource_path = os.path.join(os.path.split(__file__)[0], "resources")
print resource_path
В C: Temp Работаю, я создаю приложение, топапп.py, следующим образом:
import topp
import topp.sub1
import topp.sub2
Это резюмирует приложение, используя topp
пакет и подпакинги. Затем я запускаю:
C:\temp\work>topapp Traceback (most recent call last): File "C:\temp\work\topapp.py", line 1, in import topp ImportError: No module named topp
Это как и ожидалось. Мы установили PythonPath для моделирования, наличие нашей упаковки на пути:
C:\temp\work>set PYTHONPATH=c:\temp C:\temp\work>topapp c:\temp\topp\resources c:\temp\topp\sub1\resources c:\temp\topp\sub2\resources
Как вы можете видеть, пути ресурса, правильно разрешаемые местоположением фактических (суб) пакетов на пути.
Обновлять: ЗдесьСоответствующая документация Py2exe.
@ Pycon2009, была презентация на Distutils и Setuptools. Вы можете найти все видео здесь
Яйца и развертывание настройки в Python - Часть 1
Яйца и развертывание настройки в Python - Часть 2
Яйца и развертывание настройки в Python - Часть 3
В этих видео они описывают, как включить статические ресурсы в ваш пакет. Я считаю, что это в части 2.
С помощью Setuptools вы можете определить зависимость, это позволит вам иметь 2 пакета, которые используют ресурсы из 3 -го пакета.
Setuptools также дает вам стандартный способ получить доступ к этим ресурсам и позволяет использовать относительные пути внутри ваших пакетов, что устраняет необходимость беспокоиться о том, где установлены ваши пакеты.