作为 python 的新手,我最近才发现通过将文件放在__main__.py
文件顶部直接执行 .zip 文件的能力。这适用于 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 包含:
. |-- 应用 | |-- 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 机器上,进程没有打开文件句柄或将内存映射到它自己的 zipfile,所以大概没有办法“神奇地”访问它。
但是,创建自己的访问权限并不难。创建一个__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')