Last updated: Apr 8, 2024
Reading timeยท4 min
The Python "ValueError: I/O operation on closed file" occurs when you try to perform an operation on a closed file.
To solve the error, make sure to indent the code that tries to access the file
correctly if using the with open()
statement.
Here is an example of how the error occurs.
file_name = 'example.txt' with open(file_name, 'w', encoding='utf-8') as my_file: my_file.write('first line' + '\n') print(my_file.closed) # ๐๏ธ True # ๐๏ธ Forgot to indent the code # โ๏ธ ValueError: I/O operation on closed file. my_file.write('second line' + '\n') my_file.write('third line' + '\n')
We forgot to indent the code that writes to the file, so the with open()
statement automatically closed the file and we performed an I/O operation on a
closed file.
Trying to access the file
object outside the
with
block causes the error.
with
block, the file is automatically closed.with open()
statementTo solve the error, make sure to indent your code correctly and move it into the
with
statement without mixing tabs and spaces.
file_name = 'example.txt' with open(file_name, 'w', encoding='utf-8') as my_file: my_file.write('first line' + '\n') print(my_file.closed) # ๐๏ธ False # โ the code is indented correctly my_file.write('second line' + '\n') my_file.write('third line' + '\n') # ๐๏ธ the file is closed here (outside while block) print(my_file.closed) # ๐๏ธ True
The with open()
syntax takes care of automatically closing the file even if an
exception is thrown.
You might get the error if you use tabs and spaces to intend a line of code.
To solve the error, rewrite the line and only use tabs or spaces.
file_name = 'example.txt' with open(file_name, 'w', encoding='utf-8') as my_file: my_file.write('first line' + '\n') # โ Uses only tabs OR spaces my_file.write('second line' + '\n') # โ๏ธ Uses tabs AND spaces
Mixing tabs and spaces when indenting a line often causes issues in Python.
with
blockIf you try to interact with the file object outside of the with open()
statement, the file is already closed.
Your code has to be correctly indented and placed into the with open()
block
to be able to interact with the file.
Here is another example.
file_name = 'example.txt' with open(file_name, 'w', encoding='utf-8') as my_file: # โ Code is indented correctly my_file.write('first line' + '\n') my_file.write('second line' + '\n') my_file.write('third line' + '\n')
with open()
statement.Any code that tries to access the file needs to be indented correctly.
with
statementAlternatively, you can store the file object into a variable and manually close it.
file_name = 'example.txt' my_file = open(file_name, 'w', encoding='utf-8') my_file.write('first line' + '\n') my_file.write('second line' + '\n') my_file.write('third line' + '\n') print(my_file.closed) # ๐๏ธ False my_file.close() # ๐๏ธ Manually close file print(my_file.closed) # ๐๏ธ True
When we use the
open() function
without the with open
statement, we have to manually close the file.
with open()
syntax as it automatically closes the file after we are done.Manually closing the file can cause issues if an error occurs before the
file.close()
line can run.
closed
property to check if a file has been closedYou can use the closed
property on a file object to check if it's closed or
not.
file_name = 'example.txt' with open(file_name, 'w', encoding='utf-8') as my_file: # โ Code is correctly indented my_file.write('first line' + '\n') my_file.write('second line' + '\n') my_file.write('third line' + '\n') print(my_file.closed) # ๐๏ธ False print(my_file.closed) # ๐๏ธ True if my_file.closed: # ๐๏ธ This runs print('The file is closed.') else: print('The file is NOT closed')
The lines below the with
statement are not indented, so the file is already
closed at that point.
If you need to check if a file is not closed, use the not
operator.
file_name = 'example.txt' with open(file_name, 'w', encoding='utf-8') as my_file: # โ Code is correctly indented my_file.write('first line' + '\n') my_file.write('second line' + '\n') my_file.write('third line' + '\n') print(my_file.closed) # ๐๏ธ False if not my_file.closed: print('The file is NOT closed') else: # ๐๏ธ This runs print('The file is closed.')
The if
block is only run if the file is not closed.
You might also get the error when interacting with CSV files.
import csv with open('employees.csv', 'w', newline='', encoding='utf-8') as csvfile: fieldnames = ['first_name', 'last_name'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) print(csvfile.closed) # ๐๏ธ False # ๐๏ธ Forgot to indent code ๐๏ธ print(csvfile.closed) # ๐๏ธ True # โ๏ธ ValueError: I/O operation on closed file. writer.writeheader() writer.writerow({'first_name': 'Alice', 'last_name': 'Smith'})
Notice that we forgot to indent the code that uses the writeheader()
and
writerow()
methods.
The file has already been closed once we exit the with open()
statement.
To solve the error indent the code that interacts with the CSV file object.
import csv with open('employees.csv', 'w', newline='', encoding='utf-8') as csvfile: fieldnames = ['first_name', 'last_name'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) print(csvfile.closed) # ๐๏ธ False # โ Code is now indented correctly writer.writeheader() writer.writerow({'first_name': 'Alice', 'last_name': 'Smith'}) writer.writerow({'first_name': 'Bob', 'last_name': 'Smith'}) print(csvfile.closed) # ๐๏ธ True
The code is now correctly indented so we can safely call the writerow()
method.
The with open()
syntax takes care of automatically closing the file even if an
exception is thrown.
You can learn more about the related topics by checking out the following tutorials: