如何让Python错误信息始终最后打印?flush方案无效
问题:异常信息与正常打印输出顺序混乱的原因及修复方案
问题描述
我确信存在解决办法,但暂时未找到。我希望错误/异常信息是终端最后输出的内容,但它有时在正常打印文本之前、之后或中间出现,顺序随机。我本以为使用sys.stdout.flush()能解决问题,于是尝试了以下代码:
if __name__ == '__main__': import sys try: main() except: sys.stdout.flush() raise
但不知为何这并未生效,错误信息与正常打印文本的输出顺序仍随机。
原因是什么?该如何修复?
补充信息
- 最小可复现示例(在我的系统中可复现问题):
import sys import numpy as np def print_garbage(): print(''.join(map(chr, np.random.randint(0, 256, 100)))) raise Exception try: print_garbage() except: sys.stdout.flush() raise
- 运行环境:Windows机器,Python 3.10.0,PyCharm社区版2022.2的cmd终端
原因分析
问题核心在于标准输出(stdout)和标准错误(stderr)是两个独立的输出流,二者拥有各自的缓冲机制:
print()函数默认输出到stdout- Python的异常追踪信息默认输出到stderr
即使你刷新了stdout,stderr的缓冲状态和输出时机仍不受控制,两个流的内容会被终端异步显示,最终导致顺序混乱。你的代码只处理了stdout的刷新,完全没涉及stderr,因此无法解决问题。
修复方案
方案1:将stderr重定向到stdout
把异常信息的输出流改为stdout,让所有内容走同一个流,刷新后即可保证顺序:
import sys import numpy as np def print_garbage(): print(''.join(map(chr, np.random.randint(0, 256, 100)))) raise Exception try: print_garbage() except: sys.stdout.flush() # 将stderr重定向到stdout后再抛出异常 sys.stderr = sys.stdout raise
方案2:手动捕获并打印异常信息到stdout
使用traceback模块捕获异常信息,手动输出到stdout,确保与正常打印内容同流:
import sys import numpy as np import traceback def print_garbage(): print(''.join(map(chr, np.random.randint(0, 256, 100)))) raise Exception try: print_garbage() except: sys.stdout.flush() # 手动将异常信息打印到stdout traceback.print_exc(file=sys.stdout)
额外提示
在Windows的cmd终端或PyCharm内置终端中,两个流的缓冲行为与类Unix系统存在差异,合并流或统一输出到同一个流是最可靠的解决方式。
内容的提问来源于stack exchange,提问作者user9413641
相关产品推荐
相关产品推荐

