含alive-progress进度条的Python脚本转exe后遇FileNotFoundError
解决PyInstaller打包alive-progress时丢失grapheme数据文件的问题
问题描述
使用命令pyinstaller --console将包含alive-progress的Python脚本network_nodes_ping.py打包为Windows平台exe文件后,程序初期运行正常,但调用alive_bar时触发如下报错:
回溯(最近的调用最后): 文件 "network_nodes_ping.py", 第38行, 于 <module> 文件 "alive_progress\core\progress.py", 第106行, 于 alive_bar 文件 "alive_progress\core\configuration.py", 第149行, 于 create_context 文件 "alive_progress\core\configuration.py", 第183行, 于 lazy_init 文件 "alive_progress\core\configuration.py", 第14行, 于 _spinner_input_factory 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "alive_progress\styles\__init__.py", 第1行, 于 <module> 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "alive_progress\styles\exhibit.py", 第9行, 于 <module> 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "alive_progress\styles\internal.py", 第126行, 于 <module> 文件 "alive_progress\styles\internal.py", 第12行, 于 create_spinners 文件 "alive_progress\animations\spinners.py", 第43行, 于 frame_spinner_factory 文件 "alive_progress\animations\spinners.py", 第43行, 于 <genexpr> 文件 "alive_progress\animations\spinners.py", 第43行, 于 <genexpr> 文件 "alive_progress\utils\cells.py", 第145行, 于 to_cells 文件 "alive_progress\utils\cells.py", 第149行, 于 split_graphemes 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "grapheme\__init.py", 第9行, 于 <module> 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "grapheme\api.py", 第2行, 于 <module> 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "grapheme\finder.py", 第3行, 于 <module> 文件 "<frozen importlib._bootstrap>", 第1027行, 于 _find_and_load 文件 "<frozen importlib._bootstrap>", 第1006行, 于 _find_and_load_unlocked 文件 "<frozen importlib._bootstrap>", 第688行, 于 _load_unlocked 文件 "PyInstaller\loader\pyimod03_importers.py", 第495行, 于 exec_module 文件 "grapheme\grapheme_property_group.py", 第97行, 于 <module> 文件未找到错误:[错误号 2] 没有该文件或目录: 'C:\\Users\\BRYANV~1\\AppData\\Local\\Temp\\_MEI85082\\grapheme\\data/grapheme_break_property.json' [13328] 由于未处理的异常,脚本 'network_nodes_ping' 执行失败!
核心原因:alive-progress依赖的grapheme包需要读取grapheme_break_property.json数据文件,但PyInstaller默认不会自动打包这类非代码资源文件,导致exe运行时找不到该文件。
解决方案
方案一:直接在打包命令中添加数据文件
找到你的Python环境中grapheme包的data目录(通常在Lib\site-packages\grapheme\data),然后使用--add-data参数指定打包该目录下的所有文件:
pyinstaller --console --add-data "C:\你的Python路径\Lib\site-packages\grapheme\data\*;grapheme\data" network_nodes_ping.py
- Windows平台用分号
;分隔源路径和目标路径,目标路径对应exe解压后的相对位置,确保grapheme包能找到该文件。
方案二:通过.spec文件配置打包
- 先生成默认的spec文件:
pyinstaller --console network_nodes_ping.py
- 打开生成的
network_nodes_ping.spec,在datas列表中添加grapheme数据文件的配置:
a = Analysis( ['network_nodes_ping.py'], pathex=[], binaries=[], datas=[('C:\\你的Python路径\\Lib\\site-packages\\grapheme\\data\\*', 'grapheme\\data')], # 其他原有配置... )
- 使用spec文件重新打包:
pyinstaller network_nodes_ping.spec
方案三:修改代码适配打包环境
如果前两种方案无效,可以在代码中手动指定grapheme数据文件的路径,适配PyInstaller的临时运行目录:
import sys import os import grapheme def get_grapheme_data_dir(): # 判断是否是PyInstaller打包后的运行环境 if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, 'grapheme', 'data') # 开发环境下直接用grapheme包的data目录 return os.path.join(os.path.dirname(grapheme.__file__), 'data') # 设置环境变量告知grapheme数据文件位置 os.environ['GRAPHEME_DATA_DIR'] = get_grapheme_data_dir()
添加这段代码后,再用原命令打包即可。
内容的提问来源于stack exchange,提问作者V-Ghost
相关产品推荐
相关产品推荐

