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

Python文本文件报错:ValueError: I/O operation on closed file 求助

问题分析与修复

错误原因

你遇到的ValueError: I/O operation on closed file,是因为你将sys.stdout替换为文件对象后,关闭该文件时没有恢复原始的标准输出流。后续的print("After capture")以及读取文件后的print(i)操作,依然试图写入已经关闭的文件对象,因此触发错误。

另外代码还有两处小问题:

  • 循环内重复执行if "line 01" in lines,属于冗余操作
  • 直接打印读取的行时会包含换行符,导致输出空行

修复方案

方案1:手动保存并恢复原始stdout

import sys

def print_test():
    print("Printing testing print...!")
    print("line 01")
    print("line 02")
    print("line 03")


print("Before capture")

def main():
    # 保存原始标准输出
    original_stdout = sys.stdout
    try:
        sys.stdout = open("test.txt", 'w')
        print_test()
    finally:
        # 关闭文件并恢复原始stdout
        sys.stdout.close()
        sys.stdout = original_stdout
main()

print("After capture")

with open('test.txt', 'r') as f:
    lines = f.readlines()
    for line in lines:
        print(line.strip())  # 去除换行符,输出更整洁

    # 优化判断逻辑,避免重复执行
    if any("line 01" in line for line in lines):
        print("Found line 01")

方案2:使用上下文管理器(更优雅)

利用contextlib.redirect_stdout自动处理标准输出的替换与恢复,无需手动操作原始流:

import sys
from contextlib import redirect_stdout

def print_test():
    print("Printing testing print...!")
    print("line 01")
    print("line 02")
    print("line 03")


print("Before capture")

def main():
    with open("test.txt", 'w') as f, redirect_stdout(f):
        print_test()
main()

print("After capture")

with open('test.txt', 'r') as f:
    lines = f.readlines()
    for line in lines:
        print(line.strip())

    if any("line 01" in line for line in lines):
        print("Found line 01")

核心改进点

  • 恢复了原始标准输出流,确保后续print操作正常执行
  • 优化了目标行的判断逻辑,用any()提升效率并避免重复判断
  • 用strip()处理换行符,让输出格式更整洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:20:30