Pyinstaller打包exe出现AttributeError: 'NoneType'无write属性问题求助
PyInstaller打包Tkinter+Keras程序后运行报错:AttributeError: 'NoneType' object has no attribute 'write'
打包命令
我使用以下PyInstaller命令将Python程序打包为exe文件:
pyinstaller --name BrewTwin --onefile --add-data "models;models" --add-data "needed_data;needed_data" --add-data "icons;icons" --windowed --icon=icons/brewTwin_logo.ico brewTwin_brand_new.py
问题现象
打包过程无失败记录,但运行生成的exe时出现**AttributeError: 'NoneType' object has no attribute 'write'**错误,而在IDE中运行程序完全正常。错误触发在以下代码行:
self.firstoutput = self.model.predict(tf.convert_to_tensor(self.firstpredict, dtype=tf.float32))
程序背景
- 用Python 3.9编写的基于Tkinter的GUI程序,上述代码位于GUI类的
__init__方法中 - 加载的是Keras LSTM网络模型,通过
keras.models.load_model(resource_path(model_path), compile=False)加载
完整错误栈
Traceback (most recent call last): File "brewTwin_brand_new.py", line 1117, in <module> File "brewTwin_brand_new.py", line 50, in __init__ File "keras\src\utils\traceback_utils.py", line 70, in error_handler File "keras\src\utils\traceback_utils.py", line 65, in error_handler File "keras\src\engine\training.py", line 2575, in predict File "keras\src\callbacks.py", line 519, in on_predict_batch_end File "keras\src\callbacks.py", line 322, in _call_batch_hook File "keras\src\callbacks.py", line 345, in _call_batch_end_hook File "keras\src\callbacks.py", line 393, in _call_batch_hook_helper File "keras\src\callbacks.py", line 1101, in on_predict_batch_end File "keras\src\callbacks.py", line 1170, in _batch_update_progbar File "keras\src\utils\generic_utils.py", line 296, in update File "keras\src\utils\io_utils.py", line 79, in print_msg AttributeError: 'NoneType' object has no attribute 'write'
解决方法
这个错误根源是--windowed参数导致程序没有控制台输出流(sys.stdout/sys.stderr被设为None),而Keras的predict方法默认会打印进度条,尝试写入不存在的输出流引发报错。
方法1:禁用Keras进度条
在调用predict时添加verbose=0参数,关闭进度条输出:
self.firstoutput = self.model.predict( tf.convert_to_tensor(self.firstpredict, dtype=tf.float32), verbose=0 )
方法2:重定向输出流到文件
如果需要保留日志记录,可在程序最开头添加代码,将输出重定向到日志文件:
import sys import os if sys.stdout is None: # 日志文件会生成在exe所在目录 log_path = os.path.join(os.path.dirname(sys.executable), "brewTwin_log.txt") sys.stdout = open(log_path, "w", encoding="utf-8") sys.stderr = sys.stdout
方法3:取消--windowed参数打包
如果可以接受运行时显示控制台窗口,去掉--windowed参数重新打包,输出流恢复正常后不会触发错误。
内容的提问来源于stack exchange,提问作者Florexx
相关产品推荐
相关产品推荐

