当 pyinstaller sys._MEIPASS 不起作用时,该怎么办?

问题描述 投票:0回答:1

这是一个例子,它实际上是有效的,所以它实际上并不能说明我的问题,只是为了奠定讨论基础:

mkdir C:/test/testpyinst
cd C:/test/testpyinst

这里有

main.py

#!/usr/bin/env python3

import sys, os

from lib import relative_path2

def relative_path(relative_path): # https://stackoverflow.com/q/58487122
  try:
    base_path = sys._MEIPASS
    print("_MEIPASS OK {}".format(base_path))
  except Exception:
    base_path = os.path.abspath(".")
    print("_MEIPASS exception {}".format(base_path))
  return os.path.join(base_path, relative_path)


def main():
  print("Hello from main")
  print("relative_path {}".format(relative_path(".")))
  print("relative_path2 {}".format(relative_path2(".")))

if __name__ == '__main__':
  main()

...和

lib.py

import sys, os

def relative_path2(relative_path): # https://stackoverflow.com/q/58487122
  try:
    base_path = sys._MEIPASS
    print("_MEIPASS OK {}".format(base_path))
  except Exception:
    base_path = os.path.abspath(".")
    print("_MEIPASS exception {}".format(base_path))
  return os.path.join(base_path, relative_path)

我使用这个 -

pyinstaller
通过
python3 -m pip install pyinstaller
安装:

$ uname -s
MINGW64_NT-10.0-19045

$ python3 --version
Python 3.11.8

$ pyinstaller --version
6.5.0

当我直接从 python 运行此代码时,

_MEIPASS
正如预期不可访问:

$ python3 main.py
Hello from main
_MEIPASS exception C:/test/testpyinst
relative_path C:/test/testpyinst/.
_MEIPASS exception C:/test/testpyinst
relative_path2 C:/test/testpyinst/.

然后我使用 PyInstaller 创建一个

.exe

pyinstaller --onefile main.py

...当我运行 .exe 时,正如预期的那样,

_MEIPASS
有效:

$ ./dist/main.exe
Hello from main
_MEIPASS OK D:\msys64\tmp\_MEI199762
relative_path D:\msys64\tmp\_MEI199762/.
_MEIPASS OK D:\msys64\tmp\_MEI199762
relative_path2 D:\msys64\tmp\_MEI199762/.

所以,这是我的问题 - 在我的实际(pyqt5)项目中,

sys._MEIPASS
不起作用 - 从某种意义上说,当我尝试读取 relative_path()
 运行时,我
总是
sys._MEIPASS 中遇到异常最终
.exe
由 PyInstaller 创建
!?

我发现这个 AttributeError: 'module' object has no attribute '_MEIPASS' (redux) · Issue #1785 · pyinstaller/pyinstaller:

sys._MEIPASS
由 pyinstaller 生成的 exe 在运行任何 python 代码之前设置。我可以想到一些不被设置的原因:

  • 执行代码reload(sys)
  • 您使用的是 3.0 之前的 PyInstaller 版本
  • PyInstaller 安装不正确并且正在使用旧的 2.1 引导加载程序文件

我尝试运行

python3 -m trace --trace myprogram.py | grep reload
,显然我的程序中从未调用过 reload(sys) ...

所以,我仍然不知所措:我可以在我的项目中做什么,让

sys._MEIPASS
按预期工作?

python python-3.x pyinstaller
1个回答
0
投票

一般解决方案:将

def relative_path
尽可能靠近主文件的顶部(主文件将是提供给 PyInstaller 的文件,例如
__init__.py
),可能在第一个
import sys, os
之后 - 一开始,
sys._MEIPASS
应该可以正常工作(这可以帮助您稍后确定导致问题的确切库)。

© www.soinside.com 2019 - 2024. All rights reserved.