【问题标题】:Why can't my pyinstaller executable access data files?为什么我的 pyinstaller 可执行文件不能访问数据文件?
【发布时间】:2020-06-22 15:39:39
【问题描述】:

我已经阅读了几十篇文章,包括 pyinstaller 文档,但无法弄清楚为什么我的 pyinstaller 可执行文件不断返回 pygame.error: Couldn't open data/items/switch.png

switch.png 是脚本应该加载的许多图像中的第一个。

我正在从我的应用程序的根目录运行pyinstaller --add-data 'data:data' snake.py。这个director中唯一的东西是snake.pydata,其中data包含图像和音乐文件的子文件夹。

snake.spec 显示 datas=[('data', 'data')],,这对我来说是正确的。

我也尝试过使用 --onefile 修饰符,但每次仍然出现相同的错误。

更新:

我已确认文件在捆绑包中。我正在使用--onedir 来解决这个问题,'Dist' 目录中的目录结构反映了我的本地结构。使用--add-data="data:data",主 .py 文件旁边有一个“数据”文件夹,其中包含一个数据文件'database.xlsx' 和剩余数据文件的子目录。我收到以下消息,表明系统无法访问第一个数据文件:

Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "cronga.py", line 559, in <module>
  File "pandas/io/excel/_base.py", line 304, in read_excel
  File "pandas/io/excel/_base.py", line 824, in __init__
  File "pandas/io/excel/_xlrd.py", line 21, in __init__
  File "pandas/io/excel/_base.py", line 353, in __init__
  File "pandas/io/excel/_xlrd.py", line 36, in load_workbook
  File "xlrd/__init__.py", line 111, in open_workbook
FileNotFoundError: [Errno 2] No such file or directory: 'data/database.xlsx'
[11168] Failed to execute script cronga
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

【问题讨论】:

  • 也许您可以在可执行文件启动时记录os.getcwd() 的输出。我猜(假设你的 exe 正确打包)它是从不同的目录运行到解压的位置。
  • 感谢您提供更多详细信息,您能否打印os.path.abspath(path_to_your_data_file) 以检查文件是否存在?您是否按照以下建议使用了sys._MEIPASSminimal reproducible example 将更容易为您提供帮助。

标签: pygame conda pyinstaller


【解决方案1】:

您的 .spec 文件是什么样的?这是PyInstaller docs on adding data files

基本上你需要添加类似的东西:

a = Analysis(...
 datas=[ ('the.wav', '.') ],
 ...
 )

这会将您的声音文件('the.wav')放入已编译应用程序的根目录(第二个参数,'.')。从您的问题来看,您似乎想要复制整个数据目录。问题在于这些文件的相对路径。

然后在您的应用程序中,您可以检查您是从源代码运行还是作为已编译的可执行文件运行。我使用辅助函数:

def my_path(path_name):
    """Return the appropriate path for data files based on execution context"""
    if getattr( sys, 'frozen', False ):
        # running in a bundle
        return(os.path.join(sys._MEIPASS, path_name))
    else:
        # running live
        return path_name

那么您的应用程序代码将如下所示:

the_sound = pygame.mixer.Sound(my_path("the.wav"))

在尝试调试可执行文件时,打开命令行并从那里运行可执行文件会有所帮助,如果您已创建控制台应用程序,那么您可能仍会看到发生的回溯。

【讨论】:

  • 所以我已经尝试了帮助文件(你的和我在研究中发现的其他文件),它仍然无法从可执行文件中打开文件。我是否还需要手动将文件/目录添加到 .spec 文件中的 Analysis 类?
  • 文档声明“您可以使用--add-data 命令选项将数据文件添加到包中,或者将它们作为列表添加到规范文件中”,因此任何一种方法都可以工作。如果没有您提供的其他信息,很难为您提供进一步的帮助。您是否已验证文件是否包含在您的捆绑包中?您是否打印了路径以验证您的程序是否正在尝试从正确的位置加载文件?请更新您的问题,详细说明您的诊断工作。
猜你喜欢
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多