Eel项目PyInstaller打包exe加--noconsole时出现AttributeError错误
Eel打包带
--noconsole参数时出现AttributeError错误 问题详情
使用Eel开发Python项目,执行打包命令时添加--noconsole参数(需要无控制台运行),生成的exe文件启动时抛出以下错误:
Traceback (most recent call last): File "hello.py", line 1, in <module> import eel File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module File "eel\__init__.py", line 8, in <module> File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module File "bottle.py", line 73, in <module> AttributeError: 'NoneType' object has no attribute 'write'
已尝试的操作:
- 替换auto py-to-exe打包,问题复现
- 打包Eel官方Hello World示例,问题依旧
- 切换Python版本3.8.9、3.9.13、3.10.8,未解决
- 找到类似问题,但不清楚
--add-data参数的正确配置
错误原因
当使用--noconsole参数时,PyInstaller会将sys.stdout和sys.stderr设置为None,而Eel依赖的Bottle库在初始化时尝试写入标准输出,导致抛出AttributeError。
解决方法
方法1:重定向标准输出到空设备
在导入Eel之前,强制将sys.stdout和sys.stderr重定向到空设备,避免Bottle调用None.write():
import sys import os # 处理无控制台时stdout/stderr为None的情况 if sys.stdout is None: sys.stdout = open(os.devnull, 'w') if sys.stderr is None: sys.stderr = open(os.devnull, 'w') import eel # 后续Eel代码... eel.init('web') eel.start('index.html')
方法2:正确配置PyInstaller的--add-data参数
使用Eel打包命令时,需要显式将Eel和Bottle的相关文件添加到打包资源中,Windows系统命令示例:
python -m eel hello.py web --onefile --noconsole --add-data "%PYTHONPATH%\Lib\site-packages\eel;eel" --add-data "%PYTHONPATH%\Lib\site-packages\bottle.py;."
注:%PYTHONPATH%需替换为你的Python安装路径,比如C:\Python310
方法3:使用PyInstaller spec文件打包
编写自定义spec文件,明确指定要打包的资源和控制台模式:
a = Analysis( ['hello.py'], datas=[('web', 'web'), ('venv/Lib/site-packages/eel', 'eel'), ('venv/Lib/site-packages/bottle.py', '.')], hiddenimports=['bottle', 'eel'], ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.datas, name='hello', console=False, # 对应--noconsole参数 upx=True, )
执行打包命令:
pyinstaller hello.spec
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

