Python: могут ли исполняемые файлы zip включать файлы данных?
Являясь довольно новым для python, я только недавно обнаружил возможность непосредственного выполнения .zip файла, поместив __main__.py
файл в начало файла. Это отлично работает для кода python, но могу ли я объединить другие типы файлов и получить доступ к ним с помощью моих скриптов? Если да, то как?
Моя конечная цель состояла бы в том, чтобы связать некоторые файлы изображений вместе с кодом python в одном .zip файле, а затем иметь возможность использовать эти изображения в приложении без необходимости извлекать их на диск. Я также хотел бы связать уведомление об авторских правах, заметки о выпуске и т.д., Чтобы все приложение и его файлы данных находились в одном zip файле, который может быть выполнен без необходимости его извлечения.
Ответы
Ответ 1
Вы можете использовать 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 содержит:
.
|-- app
| |-- 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
Ответ 2
По крайней мере, на моем 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
Ответ 3
просто используйте pkgutil.get_data(), как предложено в этом ответе
Ответ 4
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')