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')
Другие вопросы по тегам