【问题标题】:Pyinstaller Unable to access Data FolderPyinstaller 无法访问数据文件夹
【发布时间】:2026-02-19 22:40:01
【问题描述】:

下面是我创建的 game.spec 文件。 运行以下命令时,应用程序被完美创建

pyinstaller --onefile game.spec

运行游戏时,无法找到任何数据文件。在进一步探索中发现它搜索目录 /Users/username 中的所有数据文件,而不是从程序运行的绝对路径。

spec 文件需要改写吗?

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['game.py'],
             pathex=['/Users/username/pythonenv/mygame'],
             binaries=[],
             datas=[('images','images'),
('fonts','fonts'),
('sounds','sounds'),
('pygame','pygame'),
('pygameMenu','pygameMenu'),
('pgzero','pgzero'),
('numpy','numpy'),
('pgzrun.py','.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='game',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='game')
app = BUNDLE(coll,
             name='game.app',
             icon=None,
             bundle_identifier=None)

【问题讨论】:

    标签: python pygame pgzero


    【解决方案1】:

    当 pyInstaller(或 cx_Freeze、py2exe 等)生成可执行文件时,所有程序文件以及 PyGame、Python 和一堆其他东西都会被压缩。

    当它运行时,首先发生的事情是解压归档文件。在某处解压。然后您的可执行文件将启动,但不是从解包位置启动。

    要解决此问题,您的脚本必须确定它运行的位置 - 即脚本的完整路径。然后使用此位置查找所有程序的额外文件。

    import sys
    import os.path
    
    if getattr(sys, 'frozen', False):
        EXE_LOCATION = os.path.dirname( sys.executable ) # cx_Freeze frozen
    else:
        EXE_LOCATION = os.path.dirname( os.path.realpath( __file__ ) ) # Other packers
    

    然后在加载文件时,用os.path.join确定完整路径:

    my_image_filename = os.path.join( EXE_LOCATION, "images", "xenomorph.png" )
    image = pygame.image.load( my_image_filename ).convert_alpha()
    
    my_sound_filename = os.path.join( EXE_LOCATION, "sounds", "meep-meep.ogg" )
    meep_sound = pygame.mixer.Sound( my_sound_filename )
    

    可能可以使用os.chdir( EXE_LOCATION ) 设置一次目录,从而减少更改,但我认为注意路径是最好的方法。

    【讨论】:

    • 感谢@Kingsley,这已经解决了与资源有关的问题