将Eel Python项目打包为.exe文件时出现AttributeError错误求助
问题场景
开发单页Eel项目,功能为用户点击按钮时获取用户ID并在Python中打印,VS Code中运行正常,但用PyInstaller或auto-py-to-exe打包为.exe后运行报错:
Traceback (most recent call last): File "ex.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 385, 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 385, in exec_module File "bottle.py", line 73, in
AttributeError: 'NoneType' object has no attribute 'write'
问题原因
Eel依赖的Bottle框架在打包后的EXE环境中,尝试写入未正确初始化的标准输出流(sys.stdout为None),导致触发该错误。
解决方法
1. 提前初始化标准流(推荐)
在项目主Python文件的最开头添加以下代码,强制初始化标准输出和错误输出:
import sys import os # 确保标准输出/错误流存在,避免为None if sys.stdout is None: sys.stdout = open(os.devnull, 'w') if sys.stderr is None: sys.stderr = open(os.devnull, 'w') # 后续导入Eel及其他模块 import eel # 你的项目代码...
2. 打包时保留控制台
使用PyInstaller打包时添加--console参数,让EXE运行时保留控制台窗口,确保标准流正常初始化:
pyinstaller --onefile --console your_main_script.py
若不需要显示控制台,可先用该参数测试打包是否正常,确认后再结合方法1的代码,改用--windowed参数打包。
3. 修改Bottle源码(临时方案)
找到Python环境中的bottle.py文件,定位到第73行(报错行),添加sys.stdout非空判断:
import sys # 原代码可能为sys.stdout.write(...),修改为: if sys.stdout is not None: sys.stdout.write('Bottle v%s server starting up (using %s)...\n' % (__version__, server_adapter)) sys.stdout.write('Listening on http://%s:%d/\n' % (host, port)) sys.stdout.write('Hit Ctrl-C to quit.\n\n')
4. 更新依赖版本
确保使用最新版的Eel和PyInstaller,旧版本可能存在打包兼容性问题:
pip install --upgrade eel pyinstaller
内容的提问来源于stack exchange,提问作者Satyajit Biswal

