python: могут ли исполняемые zip-файлы включать файлы данных?
Будучи довольно новым для python, я только недавно обнаружил возможность прямого запуска.zip-файла, поместив __main__.py
файл в верхней части файла. Это прекрасно работает для кода Python, но могу ли я связать другие типы файлов и получить к ним доступ с помощью моих скриптов? Если так, то как?
Моей конечной целью было бы объединить некоторые файлы изображений вместе с кодом Python в один файл.zip, а затем использовать эти изображения в приложении без необходимости извлекать их на диск. Я также хотел бы объединить уведомление об авторских правах, заметки о выпуске и т. Д., Чтобы все приложение и его файлы данных были в одном zip-файле, который можно было выполнить без необходимости извлекать его куда-либо.
4 ответа
Вы могли бы использовать 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 содержит:
, |- приложение | |- im.png | `- __init__.py |- README.txt `- __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
По крайней мере, на моем компьютере с 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(), как предложено в этом ответе
pkgutil.get_data(package, resource)
берет имя пакета и ресурса. Это означает, что вы должны поместить свои файлы данных в пакет внутри zip-файла.
Так, например, ZIP-файл, содержащий:
__main__.py
zippeddata/__init__.py
zippeddata/data.txt
__init__.py
Файл может быть пустым или просто комментарием, но вам нужен zippeddata
ввоз.
Затем в __main__.py
Вы просто звоните:
data = pkgutil.get_data('zippeddata', 'data.txt')