Working with Files
Learn how to read data from files and write data to files so your programs can store information permanently.
Data that survives
When your program stores data in variables, that data disappears when the program stops running. If you want data to survive between runs, like saving user notes, scores or settings, you need to write it to a file. Reading and writing files is one of the most practical Python skills.
Use the built-in open() function to open a file. You give it the file name and a mode that tells Python what you want to do:
"r"Read. Opens an existing file. Gives an error if the file does not exist."w"Write. Creates a new file or overwrites an existing one."a"Append. Adds to the end of an existing file without deleting its content. Creates the file if it does not exist."r+"Read and write.
If you do not give a mode, Python uses "r". The most important thing to remember is the difference between "w" and "a". Opening an existing file with "w" wipes everything in it right away, even before you write a single character.
The with statement
The best way to work with files is the with statement. It automatically closes the file when you are done, even if an error happens. Always use this pattern:
with open("myfile.txt", "r") as file:
content = file.read()
print(content)
# file is automatically closed here
Read it as: "open this file and call it file while you are inside this block". When the indented block ends, Python closes the file for you.
Why does closing matter? An open file holds resources, and text you wrote might not be fully saved until the file closes. Forgetting to close files can cause lost data and strange bugs. The with statement makes forgetting impossible, so use it every time.
Files live in a folder. If you give only a name like "myfile.txt", Python looks in the folder where you ran the program. To use another place, give a full path, for example "/home/alice/notes/myfile.txt" or "C:/Users/alice/myfile.txt".
Writing and appending
with open("notes.txt", "w") as file:
file.write("This is my first line.\n")
file.write("This is my second line.\n")
file.write("This is my third line.\n")
The \n is a newline character. It moves to the next line. Without it, all the text lands on one line, because write() adds exactly what you give it and nothing more. Also, write() only accepts strings, so convert numbers with str() first.
To add to a file without deleting what is already there, use append mode:
with open("notes.txt", "a") as file:
file.write("This line is added at the end.\n")
Run the write program twice and notes.txt still has just three lines, because "w" starts fresh each time. Run the append program twice and the new line appears twice. You can also write many lines at once with writelines():
lines = ["one\n", "two\n", "three\n"]
with open("numbers.txt", "w") as file:
file.writelines(lines)
Reading from a file
There are three common ways to read. Pick the one that matches what you need:
with open("notes.txt", "r") as file:
content = file.read() # read entire file as one string
print(content)
with open("notes.txt", "r") as file:
lines = file.readlines() # read all lines into a list
for line in lines:
print(line.strip()) # strip() removes the newline at the end of each line
with open("notes.txt", "r") as file:
for line in file: # loop directly over the file (memory efficient)
print(line.strip())
read()gives one big string. Good for small files.readlines()gives a list with one string per line, each ending in\n.- Looping over the file reads one line at a time, so it works even for huge files.
Each line you read still has its newline at the end. That is why we use strip(), otherwise print would add a second blank line. A file also remembers where you are. After read() reaches the end, a second read() in the same block returns an empty string.
When the file is missing
If you try to open a file that does not exist in read mode, Python raises a FileNotFoundError. Handle it gracefully with try and except:
try:
with open("mydata.txt", "r") as file:
content = file.read()
print(content)
except FileNotFoundError:
print("Error: The file was not found.")
Without this, the program crashes and the user sees a scary message. With it, you show a friendly note, or you could create the file instead. You can also check first whether a file exists using the os module:
import os
if os.path.exists("mydata.txt"):
print("The file is there.")
else:
print("No such file yet.")
A missing file is the most common file problem. The second most common is a wrong folder. If Python says it cannot find a file that you can see, check where your terminal is running from.
A simple note-taking program
Here is everything together. This program saves notes to a file, so they are still there the next time you run it:
FILENAME = "notes.txt"
def save_note(note):
with open(FILENAME, "a") as file:
file.write(note + "\n")
def read_notes():
try:
with open(FILENAME, "r") as file:
lines = file.readlines()
if not lines:
print("No notes yet.")
else:
for i, line in enumerate(lines, 1):
print(f"{i}. {line.strip()}")
except FileNotFoundError:
print("No notes yet.")
while True:
print("\n1. Add a note")
print("2. Read notes")
print("3. Quit")
choice = input("Choose: ")
if choice == "1":
note = input("Enter your note: ")
save_note(note)
print("Note saved.")
elif choice == "2":
read_notes()
elif choice == "3":
print("Goodbye!")
break
else:
print("Please choose 1, 2, or 3.")
Look at the pieces. Two small functions do the file work. A while True loop shows the menu. if and elif pick the action. try and except handle the first run, when notes.txt does not exist yet. That is functions, loops, decisions and files all in one place.
Working with lines and data
Once you can read a file, you can process what is inside. Here is a program that counts the lines and words in a file:
line_count = 0
word_count = 0
with open("notes.txt", "r") as file:
for line in file:
line_count += 1
word_count += len(line.split())
print(f"Lines: {line_count}, Words: {word_count}")
Files are plain text, so everything you read is a string. For numbers, convert them:
# scores.txt has one number per line
total = 0
with open("scores.txt", "r") as file:
for line in file:
total += int(line.strip())
print(total)
To save structured data like dictionaries, you can use the json module, which the modules lesson covers. For simple tables, a text line like Alice,25,London can be split with line.strip().split(",").
Common mistakes
- Using
"w"when you meant"a". This wipes the old content. Think before you write. - Forgetting
\n. All lines end up joined together. - Wrong folder. The file is somewhere else. Print
os.getcwd()to see where Python is looking. - Not converting numbers.
file.write(5)raises aTypeError. Usestr(5). - Reading after the file is closed. Do your reading inside the
withblock.
with open("data.txt", "r") as file:
pass
file.read() # ValueError: I/O operation on closed file
When a file operation fails, read the error name. FileNotFoundError means the path is wrong, and PermissionError means you are not allowed to use that location.
Key takeaways
- Files keep data after the program stops
open(name, mode)uses"r"to read,"w"to write (and erase),"a"to append- Always use
with open(...) as file:so the file closes by itself write()needs strings and needs\nfor line breaksread(),readlines()and looping over the file are the three ways to readstrip()removes the newline at the end of each line- Catch
FileNotFoundErrorwithtryandexcept