23

作为 python 的新手,我最近才发现通过将文件放在__main__.py文件顶部直接执行 .zip 文件的能力。这适用于 python 代码,但我可以捆绑其他类型的文件并使用我的脚本访问它们吗?如果是这样,怎么做?

我的最终目标是将一些图像文件与 python 代码捆绑在一个 .zip 文件中,然后能够在应用程序中使用这些图像,而无需将它们提取到磁盘。我还想捆绑版权声明、发行说明等,以便整个应用程序及其数据文件位于一个 zip 中,无需将其提取到某个地方即可执行。

4

4 回答 4

21

您可以使用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
于 2011-03-18T18:55:31.487 回答
6

至少在我的 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
于 2011-03-18T18:08:56.723 回答
6

只需按照此答案中的建议使用pkgutil.get_data()

于 2011-03-18T18:41:48.597 回答
0

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')
于 2011-03-18T18:54:06.703 回答