ValueError: I/O operation on closed file in Python [Solved]

avatar
Borislav Hadzhiev

Last updated: Apr 8, 2024
4 min

banner

# ValueError: I/O operation on closed file in Python

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.

valueerror io operation on closed file

Here is an example of how the error occurs.

main.py
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')

writing data to closed file

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.

Once you exit the with block, the file is automatically closed.

# Indent your code correctly in the with open() statement

To solve the error, make sure to indent your code correctly and move it into the with statement without mixing tabs and spaces.

main.py
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

indent code correctly

The with open() syntax takes care of automatically closing the file even if an exception is thrown.

# Make sure you haven't mixed tabs and spaces

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.

main.py
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.

# Make sure to NOT interact with the file object outside the with block

If 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.

main.py
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')

only use file object inside with block

Make sure you don't have code that tries to access the file after the with open() statement.

Any code that tries to access the file needs to be indented correctly.

# Using the open() function instead of the with statement

Alternatively, you can store the file object into a variable and manually close it.

main.py
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

using open function instead of with statement

When we use the open() function without the with open statement, we have to manually close the file.

Note that it's better to use the 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.

# Using the closed property to check if a file has been closed

You can use the closed property on a file object to check if it's closed or not.

main.py
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')

using closed property to check if file has been closed

The lines below the with statement are not indented, so the file is already closed at that point.

# Checking if the file has not been closed

If you need to check if a file is not closed, use the not operator.

main.py
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.

# The error also occurs when interacting with CSV files

You might also get the error when interacting with CSV files.

main.py
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.

main.py
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.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev