5

我正在尝试使用带有科学、MMTK 等模块的 pyinstaller 编译 python 脚本。Pyinstaller 无法包含一些 .pyd 模块,因此我将它们手动复制到 dist 文件夹中。当我执行编译的 exe 时,它​​给了我以下错误:-

C:\Python27\hello\dist\hello>hello.exe
回溯(最近一次通话最后):
  文件“”,第 21 行,在
  importHook 中的文件“C:\Python27\iu.py”,第 436 行
    mod = _self_doimport(nm, ctx, fqname)
  文件“C:\Python27\iu.py”,第 521 行,在 doimport
    mod.__dict__中的exec co
  <module> 中的文件“c:\Python27\hello\build\pyi.win32\hello\outPYZ1.pyz/visual”,第 1 行
  importHook 中的文件“C:\Python27\iu.py”,第 436 行
    mod = _self_doimport(nm, ctx, fqname)
  文件“C:\Python27\iu.py”,第 521 行,在 doimport
    mod.__dict__中的exec co
  <module> 中的文件“c:\Python27\hello\build\pyi.win32\hello\outPYZ1.pyz/visual.visual_all”,第 1 行
  importHook 中的文件“C:\Python27\iu.py”,第 436 行
    mod = _self_doimport(nm, ctx, fqname)
  文件“C:\Python27\iu.py”,第 521 行,在 doimport
    mod.__dict__中的exec co
  <module> 中的文件“c:\Python27\hello\build\pyi.win32\hello\outPYZ1.pyz/vis”,第 13 行
  importHook 中的文件“C:\Python27\iu.py”,第 436 行
    mod = _self_doimport(nm, ctx, fqname)
  文件“C:\Python27\iu.py”,第 521 行,在 doimport
    mod.__dict__中的exec co
  <module> 中的文件“c:\Python27\hello\build\pyi.win32\hello\outPYZ1.pyz/vis.ui”,第 3 行
  importHook 中的文件“C:\Python27\iu.py”,第 477 行
    mod = self.doimport(nm, ctx, ctx+'.'+nm)
  文件“C:\Python27\iu.py”,第 521 行,在 doimport
    mod.__dict__中的exec co
  <module> 中的文件“c:\Python27\hello\build\pyi.win32\hello\outPYZ1.pyz/vis.materials”,第 159 行
  文件“c:\Python27\hello\build\pyi.win32\hello\outPYZ1.pyz/vis.materials”,第 129 行,在 loadTGA
IOError: [Errno 2] 没有这样的文件或目录:'c:\\Python27\\hello\\build\\pyi.win32\\hello\\outPYZ1.pyz/turbulence3.tga'

顺便说一句,我可以在该位置看到 outPYZ1.pyz 文件。任何的想法?

4

1 回答 1

13

这不是关于 pyd 文件,而是关于找不到 TGA 文件。当应用程序由 pyinstaller 打包时,您需要调整您的软件以查看不同的位置。根据访问数据文件

在 --onedir 发行版中,这很容易:将您的数据文件列表(以 TOC 格式)传递给 COLLECT,它们将显示在发行版目录树中。(name, path, 'DATA') 元组中的名称可以是相对路径名。然后,在运行时,您可以使用这样的代码来查找文件:

os.path.join(os.path.dirname(sys.executable), relativename))

在 --onefile 发行版中,数据文件捆绑在可执行文件中,然后在运行时由 C 代码提取到工作目录中(它也能够重建目录树)。工作目录最好通过 os.environ['_MEIPASS2'] 找到。因此,您可以通过以下方式访问这些文件:

os.path.join(os.environ["_MEIPASS2"], relativename))

因此,如果您在程序中打开文件,请不要这样做:

fd = open('myfilename.tga', 'rb')

此方法是从当前目录打开文件。所以它对 pyinstaller 不起作用,因为当前目录与放置数据的位置不同。

根据您是否使用--onefile,您必须更改为:

import os
filename = 'myfilename.tga' 
if '_MEIPASS2' in os.environ:
    filename = os.path.join(os.environ['_MEIPASS2'], filename))
fd = open(filename, 'rb')

或者如果是--onedir

import os, sys
filename = os.path.join(os.path.dirname(sys.executable), 'myfilename.tga'))
fd = open(filename, 'rb')
于 2012-03-04T10:10:31.907 回答