You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

临时修改sys.stdout报错ValueError:对已关闭文件执行I/O操作

解决「ValueError: I/O operation on closed file」报错问题

咱们来拆解一下你遇到的问题,先看你执行的代码:

>>> import sys 
>>> sys.stdout = open('myfile.log', 'w') 
>>> print('escribo en el archivo log...') 
>>> print('todavia en el archivo log...') 
>>> sys.stdout.close() 
>>> open('myfile.log').read() 

报错原因分析

你看到的这个报错,并不是最后一行open('myfile.log').read()导致的,而是在你执行sys.stdout.close()之后,Python的交互式环境(也就是你用的命令行shell)尝试向标准输出(stdout)写入下一个提示符>>>,但此时你已经把sys.stdout指向的文件对象关闭了,这就触发了「对已关闭文件执行I/O操作」的错误。

简单来说:你替换了默认的stdout为自定义的文件,关闭这个文件后,系统再想往stdout写东西(比如命令提示符)就失败了。

关于Python版本差异的疑问

这个问题和Python 3.4与3.6.5的版本差异完全无关——在这两个版本的交互式环境中,这个行为是一致的,都会出现同样的报错。

修复方案

手动恢复原stdout

在关闭自定义的stdout文件之前,先保存并恢复原来的标准输出对象:

>>> import sys
>>> # 先保存原始的stdout对象
>>> original_stdout = sys.stdout
>>> sys.stdout = open('myfile.log', 'w')
>>> print('escribo en el archivo log...')
>>> print('todavia en el archivo log...')
>>> # 先关闭文件,再恢复stdout
>>> sys.stdout.close()
>>> sys.stdout = original_stdout
>>> # 现在执行读取操作就不会报错了
>>> open('myfile.log').read()
'escribo en el archivo log...\ntodavia en el archivo log...\n'

更优雅的上下文管理器方式

使用contextlib.redirect_stdout可以自动帮你处理stdout的恢复,避免手动操作出错:

from contextlib import redirect_stdout

with open('myfile.log', 'w') as log_file:
    with redirect_stdout(log_file):
        print('escribo en el archivo log...')
        print('todavia en el archivo log...')

# 退出with代码块后,stdout会自动恢复为默认值
print("现在又可以正常在控制台输出了")
print("读取日志内容:", open('myfile.log').read())

内容的提问来源于stack exchange,提问作者FedePython

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:05:24