2

我正在许多客户端机器上的一台服务器机器上运行一个 py2exe 编译的 python 程序(映射到每台机器上的网络驱动器,比如 W:)。

对于 Windows XP 和更高版本的机器,到目前为止,Python 获取 W:\python23.dll 的问题为零(是的,我使用 Python 2.3.5 来兼容 W98 等等)。然后它将使用 W:\zlib.pyd 解压缩包含所有 .pyc 文件(如 os 等)的 W:\library.zip,然后将其导入并且程序运行没有问题。

我遇到的问题是在一些 Windows 98 SE 机器上(注意:一些 Windows 98 SE 机器,其他机器似乎没有明显问题)。发生的情况是,程序从 W: 运行,我假设找到了 W:\python23.dll(因为我得到 Python ImportErrors,我们需要能够执行 Python import 语句),但是有几件事不起作用:

1)如果 W:\library.zip 包含 .pyc 文件的唯一副本,我会得到 ZipImportError: can't decompress data; zlib not available(废话,考虑到 W:\zlib.pyd 是可用的,并且可以在同一网络上的 XP 和更高版本的机器上正常工作)。

2) 如果 .pyc 文件实际上是通过 py2exe 捆绑在 python exe 中,或者放在与 .exe 相同的目录中,或者放在一个命名的子目录中,然后将其设置为 PYTHONPATH 变量的一部分(例如 W:\pylib ),我得到ImportError: no module named os(os 是第一个导入的模块,在 sys 和其他任何东西之前)。

想一想,如果 os 在它之前被导入, sys.path 将无法搜索?我将尝试切换这些导入的顺序,但我的问题仍然存在:为什么这是一个零星的问题,在某些网络上工作而不在其他网络上工作?我将如何强制 Python 找到捆绑在我运行的可执行文件中的文件?我可以立即访问正在工作的 Windows 98 SE 机器,但我只能在每天早上在他们的商店开业之前访问不工作的机器(我的一位客户)。

提前致谢!


编辑:好的,向前迈出了一大步。使用 PY2EXE_VERBOSE 调试后,特定 W98SE 机器上出现的问题是它在查找导入时没有使用正确的路径语法。首先,它似乎没有读取 PYTHONPATH 环境变量(可能有一个我不知道的特定于 py2exe 的变量,比如 PY2EXE_VERBOSE)。

其次,它在放弃之前只在一个地方查找(如果文件捆绑在 EXE 中,它会在那里查找。如果没有,它会在 library.zip 中查找)。

编辑 2:事实上,据此,Python解释器中的 sys.path 与 Py2exe 可执行文件之间存在差异。具体来说,sys.path contains only a single entry: the full pathname of the shared code archive.布拉。没有退路?甚至没有当前的工作目录?我会尝试添加W:\到 PATH,但 py2exe 不符合任何类型的系统库定位标准,所以它不起作用。

现在是有趣的一点。它尝试加载 atexit、os 等的路径是:

W:\\library.zip\<module>.<ext>

请注意 library.zip 后的单斜杠,但驱动器号后的双斜杠(如果这是有意的并且应该有效,请纠正我)。看起来如果这是一个字符串文字,那么由于斜杠没有加倍,它被读取为(无效)转义序列并打印原始字符(给出W:\library.zipos.pyd, W:\library.zipos.dll, ...而不是斜杠);如果它不是字符串文字,则双斜杠可能不会自动进行规范路径(应该如此),因此双斜杠会混淆模块加载器。就像我说的,我不能仅仅set PYTHONPATH=W:\\library.zip\\因为它忽略了那个变量。

在我的程序开始时使用 sys.path.append 可能是值得的,但是硬编码模块路径绝对是最后的手段,特别是因为问题发生在过时操作系统的 ONE 配置中。

有任何想法吗?我有一个,这是sys.path我需要os的。另一个是再次附加os.getenv('PATH')或添加os.getenv('PYTHONPATH')到 sys.path...,需要os模块。该site模块也无法初始化,所以我不能使用 .pth 文件。

我最近还在程序开始时尝试了以下代码:

for pth in sys.path:
    fErr.write(pth)
    fErr.write(' to ')
    pth.replace('\\\\','\\') # Fix Windows 98 pathing issues
    fErr.write(pth)
    fErr.write('\n')

但它无法加载 linecache.pyc 或其他任何内容;它实际上无法从事物的外观上执行这些命令。有什么方法可以使用不需要 linecache 来动态修改 sys.path 的内置功能?还是我只能硬编码正确的 sys.path?

4

1 回答 1

2

这不是一个直接的答案,但可能会有所帮助。你熟悉-vPython 中的选项吗?键入python -h以了解更多信息。注意PYTHONVERBOSEpy2exe'd 脚本的环境变量的等效项是PY2EXE_VERBOSE,除了作者在这篇文章中几乎没有描述。显然它可以取值 1 或 2,基本上类似于-vand ,尽管这与PYTHONVERBOSE-vv的工作方式略有不同。

还要注意您的 sys.path 想法:您是否已经导入sys不会影响您是否可以 import os。也就是说,Python 路径(在 中可见sys.path)总是可用的,因为它反映了解释器的内部特性,无论您是否导入了 sys 模块。

与许多其他模块一样,sys它是内置的,因此即使您的应用程序几乎完全瘫痪,它也应该始终可以导入。如果它有帮助,您可以使用sys.builtin_module_names它们来查看它们对于您的 Python 版本是什么。如果解释器正在运行,那么所有信息都是可用的,那么以下可能是您可以制作的最小的有用程序,以查看您所拥有的内容:

import sys
print sys.builtin_module_names

另外,我建议不要尝试将 .pyc 文件捆绑在 .exe 中之类的任何花哨的事情。你已经有足够的工作来阻止你支持 Win98,如果我是你,我会选择最简单的方法,让我完成工作并进入更有趣的领域。如果您可以正常安装 Python 并从源代码运行,您绝对应该考虑它!:)

编辑为包含指向 PY2EXE_VERBOSE 信息的链接,每条评论由 darvids0n 提供。

于 2010-01-05T23:42:50.820 回答