«Более простое» решение - установить zip_safe=False
в настройках вашего пакета (setup.py
или setup.cfg
), чтобы избежать установки пакета в виде яйца с молнией.Поскольку большинство установок выполняется с помощью pip
, который никогда не создает инсталляции с заархивированными яйцами, в любом случае запуск установки с заархивированными пакетами происходит в любом случае более редко.zipfile для добавления в sys.path
, вариант использования которого вы можете не поддерживать.Это другая форма упакованных пакетов;яйца - это zip-файлы для одного устанавливаемого проекта (поддерживаются pkg_resources
), которые хранятся в каталоге, указанном в sys.path
.pkg_resources
может поддерживать только второе, а не первое.
Если вы хотите поддержать яйцо с молнией, тогда для вашего конкретного случая будет проще использовать pkg_resources
APIдля извлечения ресурса , поскольку, хотя он может быть «медленнее», он также поддерживает полные деревья каталогов.Из документации resource_filename()
:
Если указанный ресурс является каталогом, то все ресурсы в этом каталоге (включая подкаталоги) также извлекаются.
Я быиспользуйте его следующим образом:
try:
www_location = pkg_resources.resource_filename("dv", "www_folder")
shutil.copytree(www_location, dir_path)
finally:
pkg_resources.cleanup_resources()
Ресурсы внутри пакетов, найденных в zip-файле, непосредственно добавленном в sys.path
, недоступны через pkg_resources
.Для этого вам потребуется более новый importlib.resources
модуль (или backport ), но этот API не поддерживает произвольные структуры каталогов.Функциональная документация importlib.resources.path()
гласит:
package - это либо имя, либо объект модуля, который соответствует требованиям Package
. resource - имя ресурса, который открывается в пакете;он может не содержать разделителей пути и может не иметь подресурсов (т. е. это не может быть каталог ).
(выделено жирным шрифтом).
Хотя вы можете найти каталоги в пакете, используя importlib.resources.contents()
, вы не можете получить доступ к содержимому этих каталогов, если они сами не являются пакетами Python (поэтому в них есть файл __init__.py
). реализация этих функций для традиционных, не заархивированных пакетов по-прежнему даст вам доступ к каталогу при использовании importlib.resources.path()
, вы не можете сделать то же самое, когда пакет содержится в архиве .zip
.
importlib.resources
- лучший путь поддержки в будущем.Чтобы поддержать это, вы можете заархивировать www_folder
дерево ресурсов в вашем исходном и колесном дистрибутивах , а затем использовать with importlib.resources.path("dv", "www_folder.zip") as www_location: www_zip = zipfile.open(www_location)
и извлечь содержимое этого объекта zipfile к месту назначения.