Jupyter Notebook写入输出到文本文件时单元格无法结束问题排查
问题排查结论
你遇到的单元格无法执行结束的问题,是stdout重定向逻辑的漏洞导致的,具体问题点如下:
- 未提前保存原始标准输出句柄:代码里直接把
sys.stdout赋值为文件对象,但从来没有提前把默认的控制台输出句柄存到original_stdout变量里,执行到重置stdout的那行代码时会直接触发NameError,重置逻辑根本跑不通。 - 异常场景下stdout无法恢复:你把stdout重置的代码放在with块的最末尾,只要块里任意一行计算逻辑(比如DataFrame取字段、计算最值)抛出异常,重置stdout的代码就不会执行。此时
sys.stdout还指向文件对象,而with块退出时会自动关闭文件,后续Jupyter内核要往控制台输出错误提示、执行状态时,都会尝试往已关闭的文件句柄写数据,直接触发IO阻塞,单元格就会一直卡在运行状态。 - 冗余操作触发风险:用
with open()语法打开文件时,上下文管理器会在块代码执行完后自动关闭文件,不需要手动调用fs.close(),多余的关闭操作反而可能触发提前释放资源的异常。
修复后代码
把逻辑改成提前存原始stdout,用try/finally保证无论是否报错都能恢复输出句柄即可:
import sys # 第一步先保存原始标准输出 original_stdout = sys.stdout out_file = path_out + day_number + 'factsheet.txt' try: with open(out_file, 'w', encoding='utf-8') as fs: sys.stdout = fs print("Fact Sheet:") Lat_start = df.Wgs84Latitude[df.index.min()] Lon_start = df.Wgs84Longitude[df.index.min()] print("Coordinates: " , Lat_start,'°N , ', Lon_start,'°E') print("Min. Humidity: " + "{:12.2f}".format(df.humidity.min()) + " %") print("Max. Humidity: " + "{:12.2f}".format(df.humidity.max()) + " %") print("Min. Temperature: " + "{:9.2f}".format(df.temperature.min()) + " °C") print("Max. Temperature: " + "{:9.2f}".format(df.temperature.max()) + " °C") finally: # 不管代码正常跑完还是抛错,都强制恢复控制台输出 sys.stdout = original_stdout
补充:如果经常需要临时把打印输出写入文件,可以单独写一个重定向stdout的上下文管理器,避免全局修改
sys.stdout引发其他难以排查的显示问题。
内容的提问来源于stack exchange,提问作者Swawa
相关产品推荐
相关产品推荐

