添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如何解决 Python 错误 ValueError: I/O Operation on Closed File

十年 编程 经验,定期分享Python干货,大家好我是 @迹忆客 关注我不迷路。


资源管理是编程中的一个重要因素。 但通常,程序员会在不知不觉中让内存块处于打开状态,这会导致内存溢出。

然而,本文着眼于 Python 中的一个错误: ValueError: I/O operation on closed file 。 当程序员试图对在操作之间以某种方式关闭的文件执行操作时,就会发生这种情况。

ValueError: I/O operation on closed file 主要在三种情况下发生:

解决 Python 中由于缩进不当发生的错误 ValueError: I/O operation on closed file

假设程序员有一个 .csv 文件,试图使用 Python 编译器将其加载到内存中。 在 Python 中,必须创建一个对象变量来加载文件的内容以读取或写入文件。

让我们通过下面的程序来理解这一点:

import csv
# Open the file in Read mode
with open("sample_submission.csv", "r") as employees:
    read_csv = csv.reader(employees)

此程序导入库包 csv 以读取 .csv 文件。 在第二行代码中,程序使用 with 语句创建异常处理块,并使用关键字 r 将 .csv 文件 sample_submission.csv 存储在对象 employees 内部作为可读实体。

我们需要分配一些内存来读取实体员工的内存。 代码的第 3 行分配了一个内存块给 read_csv 来存储来自 employees 的内容。

如果程序员想要显示 .csv 文件中的行,需要在 for 循环中打印对象 read_csv 中的行,就像下面的代码一样:

import csv
# Open the file in Read mode
with open("sample_submission.csv", "r") as employees:
    read_csv = csv.reader(employees)
# iterate and print the rows of csv
for row in read_csv:
    print("Rows: ", row)

但是当程序员试图编译这段代码时,收到一个错误:

"C:\Users\Win 10\main.py"
Traceback (most recent call last):
  File "C:\Users\Win 10\main.py", line 8, in <module>
    for row in read_csv:
ValueError: I/O operation on closed file.
Process finished with exit code 1

因为异常处理语句with 发生 ValueError: I/O operation on closed file 错误。 如前所述,with 语句创建一个异常处理块,一旦编译器离开该块,内部启动的任何操作都会终止。

在上面的程序中,一个缩进错误导致了这个错误。 Python 编译器不使用分号来标识行尾; 相反,它使用空间。

在代码中,for 循环是在 with 块之外创建的,因此关闭了文件。 尽管 for 循环写在 with 的下面,但不正确的缩进使编译器认为 for 循环在 with 块之外。

解决此问题的方法是确定正确的缩进,如下所示:

import csv
with open("sample_submission.csv", "r") as employees:
    read_csv = csv.reader(employees)
    # for loop is now inside the with block
    for row in read_csv:
        print("Rows: ", row)

输出:

"C:\Users\Win 10\main.py"
Rows:  ['Employee ID', 'Burn Rate']
Rows:  ['fffe32003000360033003200', '0.16']
Rows:  ['fffe3700360033003500', '0.36']
Rows:  ['fffe31003300320037003900', '0.49']
Rows:  ['fffe32003400380032003900', '0.2']
Rows:  ['fffe31003900340031003600', '0.52']
Process finished with exit code 0

解决 Python 中由于在for循环中关闭文件发生的异常 ValueError: I/O operation on closed file

此示例说明如何在不使用 with 语句的情况下发生 ValueError: I/O operation on closed file 。 当 Python 脚本打开文件并在循环内写入内容时,它必须在程序结束时关闭。

但是 ValueError: I/O operation on closed file 可能是由于在循环内关闭了一个显式文件而引起的。 如上所述,with 块会关闭其中已启动的任何内容。

但是在使用 for 循环等的情况下,当文件在循环中途关闭时,会发生 ValueError: I/O operation on closed file 。 让我们通过下面的程序看看这是如何发生的:

a = 0
b = open("sample.txt", "r")
c = 5
f = open("out"+str(c)+".txt", "w")
for line in b:
    a += 1
    f.writelines(line)
    if a == c:
        a = 0
    f.close()
f.close()

上面的代码从文件 sample.txt 中读取内容,然后将这些内容写入名为 out(value of c).txt 的新文件中。

变量 b 加载了 sample.txt 文件,而变量 f 用于写入新文件。 for 循环运行 b 中加载的文件中的行数。

每次迭代增加a,而在a=5的迭代中,a的值重置为零。

完成该过程后, f.close() 被使用了两次。 第一个 f.close 清除 f,而第二个清除 b。

但是程序必须在文件关闭之前运行更多的迭代。 编译程序时,它会给出以下输出:

"C:\Users\Win 10\main.py"
Traceback (most recent call last):
  File "C:\Users\Win 10\main.py", line 8, in <module>
    f.writelines(line)
ValueError: I/O operation on closed file.
Process finished with exit code 1

发生这种情况是因为文件在 for 循环内关闭,这使得它无法为后续迭代读取文件。

由于此错误是意外导致的,解决它需要返回代码并重新检查文件关闭的位置。 如果它是一个 for 循环,那么一个文件应该在循环缩进之外关闭,这允许循环完成它的所有迭代,然后释放内存。

a = 0
b = open("sample.txt", "r")
c = 5
f = open("out"+str(c)+".txt", "w")
for line in b:
    a += 1
    f.writelines(line)
    if a == c:
        a = 0
f.close()

此处,文件在 for 循环缩进之外关闭,因此编译器在完成所有迭代后关闭文件。

编译代码时,它在创建名为 out5.txt 的文件时不会抛出任何错误:

"C:\Users\Win 10\main.py"
Process finished with exit code 0

解决对关闭的文件执行写操作导致的 ValueError: I/O operation on closed file

这是一个案例场景,程序员向之前已关闭的文件发出书面指令,编译它会产生 ValueError: I/O operation on closed file 错误。

让我们看一个例子:

with open("gh.txt", 'w') as b:
    b.write("Apple\n")
    b.write("Orange \n")
    b.write("Guava \n")
    b.close()
    b.write("grapes")

该程序加载一个 .txt 文件作为对象 b。 然后这个对象变量b用于执行.txt文件内部的写操作。

编译此代码时,发生 ValueError: I/O operation on closed file

"C:\Users\Win 10\main.py"
Traceback (most recent call last):
  File "C:\Users\Win 10\main.py", line 6, in <module>
    b.write("grapes")
ValueError: I/O operation on closed file.
Process finished with exit code 1

这是由 b.close() 语句引起的,该语句覆盖了书面语句。 编译器不再让文件被写入,即使在 with 块内也是如此。

要解决此问题,如果需要添加 b.close,则应在不使用 with 语句的情况下重写程序:

b = open("gh.txt", 'w')
b.write("Apple\n")
b.write("Orange \n")
b.write("Guava \n")