我刚刚发现 (A) 一个 ZIP 文件可以直接作为 Python 二进制文件的script
参数(通常.py
会传递一个文件)传递,并且 (B) ZIP 文件可以有任何后缀,甚至.py
可以被识别为 ZIP文件(至少在 Mac OS X 上的命令行和 Windows 上的命令行和 GUI,它似乎工作)。实现这一点的整个故事都记录在这个问题中。
这似乎对 Python 应用程序的分发非常有吸引力,因为安装程序不受欢迎,并且它具有与.jar
我们的用户习惯的存档相同的使用特性(无需安装,可以通过电子邮件发送而无需进一步存档)。命名 ZIP 存档.py
(或.pyw
)无需在客户端机器上进行任何配置即可启用此行为,除了安装 Python。
我的问题是我只能找到我发现的 (A) 部分的文档,但不能找到 (B) 部分的文档。所以我的第一个问题是 Python 如何检测作为script
参数传递的文件是 ZIP 存档而不是 Python 源文件?是否存在任何可能会随机中断的启发式方法,例如当 ZIP 存档包含一些特殊内容时(例如,看起来像 Python 代码的未压缩文件)?
第二个问题是当应用程序携带大量非代码数据文件(数十 MB)时,这种方法是否存在任何缺点,除了对这些文件的访问不透明这一事实。如果 ZIP 文件很大和/或包含很多文件,我正在考虑 ZIP 文件检测需要更长的时间。
更新
遗憾的是,到目前为止所有的答案(Joachim Sauer 的、Keith Randall 的和 Curious 的)都是错误的。Zip 规范不要求 ZIP 文件必须以特定的标头开头。Zip 文件可以在其前面添加任何数据,并且仍然是有效的 Zip 文件(这是自解压 Zip 文件的工作方式,其中文件以 Windows EXE 标头而不是任何特定于 Zip 的文件开头)。这在好奇的答案中链接的页面中进行了解释。
我猜 Python 解释器会查找 Zip 中央目录,如果有,该文件将用作 Zip 文件而不是 Python 源文件。有没有人想在他/她的答案中包含这个,以便我接受?