python: могут ли исполняемые файлы zip включать файлы данных?

Будучи довольно новым для python, я только недавно обнаружил возможность непосредственного выполнения .zip-файла, поместив файл __main__.py в начало файла. Это отлично работает для кода python, но могу ли я объединить другие типы файлов и получить доступ к ним с помощью моих скриптов? Если да, то как?

Моя конечная цель состояла в том, чтобы объединить некоторые файлы изображений вместе с кодом python в одном .zip-файле, а затем иметь возможность использовать эти изображения в приложении без необходимости извлекать их на диск. Я также хотел бы связать уведомление об авторских правах, заметки о выпуске и т. Д., Чтобы все приложение и его файлы данных находились в одном zip-файле, который может быть выполнен без необходимости его извлечения.

Вы можете использовать функции pkg_resources для доступа к файлам:

 # __main__.py import pkg_resources from PIL import Image print pkg_resources.resource_string(__name__, 'README.txt') im = Image.open(pkg_resources.resource_stream('app', 'im.png')) im.rotate(45).show() 

Где zipfile содержит:

  ,
 | - Общение
 |  | - Общение
 |  `- __init__.py
 | - Охота и рыбалка
 `- __main__.py 

Чтобы сделать исполняемый файл zipfile, запустите:

 $ echo '#!/usr/bin/env python' | cat - zipfile > program-name $ chmod +x program-name 

Чтобы проверить это:

 $ cp program-name /another-dir/ $ cd /another-dir && ./program-name 

просто используйте pkgutil.get_data (), как предложено в этом ответе

По крайней мере, на моем Linux-ящике нет открытого дескриптора файла или сопоставленной памяти процессом в свой собственный zip-файл, поэтому, по-видимому, нет возможности «магически» получить к нему доступ.

Однако создать свой собственный доступ не так уж сложно. Создайте __main__.py следующим образом:

 import os, zipfile me = zipfile.ZipFile(os.path.dirname(__file__), 'r') f = me.open('other.txt') print f.read() f.close() me.close() 

Редактировать: немного кратким. Для полноты:

 $ echo "Hello ZIP" > other.txt $ zip testo.zip __main__.py other.txt $ python testo.zip Hello ZIP 

pkgutil.get_data(package, resource) принимает имя пакета и ресурса. Это означает, что вы должны помещать файлы данных внутри пакета в zip-файл.

Так, например, zip-файл, содержащий:

 __main__.py zippeddata/__init__.py zippeddata/data.txt 

Файл __init__.py может быть пустым или просто комментарием, но вам нужно сделать zippeddata zippeddata.

Затем в __main__.py вы просто вызываете:

 data = pkgutil.get_data('zippeddata', 'data.txt')