使用Eel将Python程序打包为EXE后启动报错的解决求助
AttributeError: 'NoneType' object has no attribute 'write'的解决办法 问题场景
项目结构:
app.py(主程序文件,导入同目录utils/下的两个工具.py文件)utils/(工具脚本目录)web/(存放HTML、CSS等前端资源)
使用打包命令:
python -m eel app.py web --onedir --windowed --icon
打包过程无报错,但启动生成的.exe时触发如下错误:
Traceback (most recent call last):
File "app.py", line 1, in
File "", line 1178, in _find_and_load
File "", line 1149, in _find_and_load_unlocked
File "", line 690, in load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 352, in exec_module
File "eel_init.py", line 15, in
File "", line 1178, in _find_and_load
File "", line 1149, in _find_and_load_unlocked
File "", line 690, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 352, in exec_module
File "bottle.py", line 73, in
AttributeError: 'NoneType' object has no attribute 'write'
app.py直接运行正常,仅打包后出现异常。
问题原因
使用--windowed参数时,PyInstaller会禁用控制台输出,导致sys.stdout和sys.stderr被置为None,而Eel依赖的Bottle库在初始化时尝试写入这些流,从而触发错误。
解决方法
1. 临时移除--windowed测试
先尝试不带窗口模式打包,验证是否为输出流问题:
python -m eel app.py web --onedir --icon
若启动正常,即可确认问题根源。
2. 修复输出流(推荐)
在app.py的最顶部添加以下代码,为打包后的环境替换空输出流:
import sys if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): # 针对打包后的环境,创建虚拟输出流 class DummyStream: def write(self, data): pass def flush(self): pass sys.stdout = DummyStream() sys.stderr = DummyStream()
之后重新打包即可避免报错。
3. 检查版本兼容性
确保Eel与PyInstaller版本兼容,建议升级至最新稳定版:
pip install --upgrade eel pyinstaller
4. 手动配置spec文件(进阶)
- 生成spec文件:
python -m eel app.py web --onedir --windowed --icon --spec - 打开生成的
app.spec,在hiddenimports中添加utils下的模块(确保工具脚本被正确打包):hiddenimports=['utils.module1', 'utils.module2'], - 执行打包:
pyinstaller app.spec
内容的提问来源于stack exchange,提问作者alQ

