File Handling
Learn how to open, read, write, and append to files in Python, and why the with statement is the safest way to handle them.
Introduction
Every real program eventually needs to save information somewhere that survives after it finishes running. Variables disappear the moment your script ends, but files stick around on disk. Python's built-in file handling tools let you read data from files and write data back to them with just a few lines of code.
In this lesson, you will learn how to open files in different modes, read their contents in several ways, write and append new content, and safely check whether a file exists before working with it.
- How to open a file using open() and understand its modes.
- Why the with statement is the recommended way to handle files.
- Different ways to read a file: read(), readline(), readlines(), and looping.
- How to write new content and append to existing files.
- How to check whether a file exists before opening it.
Why File Handling Matters
Without file handling, a program can only remember things while it is running. As soon as it closes, everything is lost. Files let you store settings, logs, user data, reports, and results permanently, and share that data between different runs of a program or even between different programs.
Persistent Storage
Save data so it is still there the next time the program runs.
Data Exchange
Share information between different programs using a common file format.
Logging
Record what a program did, which is useful for debugging later.
Reports
Generate readable output files like reports, receipts, or exports.
Opening a File with open()
The built-in open() function is how Python connects to a file on disk. It takes a file path and a mode, and returns a file object you can use to read or write data.
file = file = open("notes.txt", "r")
print(file)
file.close()<_io.TextIOWrapper name='notes.txt' mode='r' encoding='cp1252'>The output shows a file object, not the file's contents. To see the text inside, you need to call a reading method, which is covered shortly. Notice the call to close() at the end — forgetting this is a very common mistake, which is exactly why the with statement exists.
File Modes
The second argument to open() is the mode, which tells Python what you intend to do with the file.
| Mode | Meaning |
|---|---|
| 'r' | Read (default). Fails if the file does not exist. |
| 'w' | Write. Creates the file if missing, or erases all existing content first. |
| 'a' | Append. Creates the file if missing, adds new content to the end without erasing. |
| 'r+' | Read and write. File must already exist; does not erase content when opened. |
| 'x' | Exclusive create. Fails if the file already exists. |
Opening a file with "w" immediately erases everything already inside it, even before you write anything new. Use "a" if you want to keep the existing content and only add to it.
The with Statement (Context Manager)
Manually calling open() and close() works, but it is risky: if an error happens between those two lines, close() never runs, and the file can stay locked or lose unsaved data. The with statement solves this by automatically closing the file for you, even if an exception occurs inside the block.
with open("notes.txt", "r") as file:
content = file.read()
print(content)
# file is automatically closed here, even if an error happened above
print("Is file closed?", file.closed)Hello from notes.txt!
Is file closed? TrueThe with statement works because open() returns what Python calls a context manager — an object that knows how to set up a resource and clean it up automatically. You will learn exactly how context managers work under the hood, and how to build your own, in the dedicated Context Managers lesson later in this course.
Always prefer with open(...) as file: over manually calling open() and close(). It is shorter, safer, and is considered the standard, idiomatic way to handle files in Python.
Reading Files
Python gives you three main tools to read file content: read(), readline(), and readlines(). Assume notes.txt contains three lines: "First line", "Second line", and "Third line".
with open("notes.txt", "r") as file:
content = file.read()
print(content)First line
Second line
Third lineread() loads the entire file into a single string, including newline characters. This is convenient for small files but can use a lot of memory for very large ones.
with open("notes.txt", "r") as file:
first = file.readline()
second = file.readline()
print(repr(first))
print(repr(second))'First line\n'
'Second line\n'readline() reads just one line each time it is called, including the trailing newline character, and remembers where it left off for the next call.
with open("notes.txt", "r") as file:
lines = file.readlines()
print(lines)['First line\n', 'Second line\n', 'Third line']readlines() returns a list where each element is one line of the file, again including newline characters.
Reading Line by Line with a Loop
For large files, the most memory-efficient way to read is to loop directly over the file object. Python reads one line at a time instead of loading the whole file into memory at once.
with open("notes.txt", "r") as file:
for line in file:
print(line.strip())First line
Second line
Third lineCalling .strip() removes the trailing newline character so each printed line does not have an extra blank line after it.
Writing to a File
Use mode "w" to write new content to a file. Remember that this erases any existing content in the file first.
with open("greeting.txt", "w") as file:
file.write("Hello, Python!\n")
file.write("This is a new file.\n")
with open("greeting.txt", "r") as file:
print(file.read())Hello, Python!
This is a new file.The write() method does not add a newline automatically, so you must include \n yourself when you want the next write to start on a new line.
Appending to a File
Use mode "a" when you want to add new content to the end of a file without deleting what is already there.
with open("greeting.txt", "a") as file:
file.write("This line was appended.\n")
with open("greeting.txt", "r") as file:
print(file.read())Hello, Python!
This is a new file.
This line was appended."w" Mode
- Erases existing content first
- Good for creating a fresh file
- Risky if you forget content exists
"a" Mode
- Keeps existing content
- Good for logs and growing files
- New writes always go at the end
Checking if a File Exists
Opening a file that does not exist in "r" mode raises a FileNotFoundError. You can avoid this by checking whether the file exists first, using the os.path module.
import os
filename = "notes.txt"
if os.path.exists(filename):
print(f"{filename} exists, reading it now.")
with open(filename, "r") as file:
print(file.read())
else:
print(f"{filename} was not found.")notes.txt exists, reading it now.
First line
Second line
Third lineYou will learn a more robust way to handle a missing file — using try/except to catch FileNotFoundError directly — in the very next lesson on exception handling.
Common Mistakes
- Forgetting to close a file when not using with, which can lock the file or lose data.
- Opening a file with "w" when you meant "a", accidentally erasing all existing content.
- Trying to read a file that does not exist without checking first or handling the error.
- Forgetting that read(), readline(), and readlines() all include newline characters.
- Assuming file paths are always relative to the script file rather than the current working directory.
Best Practices
- Always use the with statement instead of manual open()/close() calls.
- Choose the correct mode carefully: "r" for reading, "w" to overwrite, "a" to append.
- Use os.path.exists() or a try/except block before opening a file that might be missing.
- Loop over a file object directly when reading large files, instead of read() or readlines().
- Close over file paths with clear, descriptive names to avoid overwriting the wrong file.
Frequently Asked Questions
What happens if I open a file in "r" mode and it does not exist?
Python raises a FileNotFoundError. You can prevent this by checking with os.path.exists() first, or by catching the error, which you will learn in the next lesson.
Do I still need to call close() if I use with?
No. The with statement automatically calls close() for you when the block ends, even if an error occurs inside it.
What is the difference between "w" and "a" mode?
"w" erases all existing content in the file before writing, while "a" keeps existing content and adds new content only at the end.
Can I both read and write to the same file?
Yes, using mode "r+", though it requires care with the file position. For most beginner use cases, separate read and write operations are simpler and clearer.
What is a context manager?
A context manager is an object (like the one returned by open()) that knows how to set up and automatically clean up a resource using the with statement. You will learn how to build your own in the Context Managers lesson later in this course.
Key Takeaways
- open() connects Python to a file on disk, using a mode like "r", "w", "a", or "r+".
- The with statement automatically closes files and is safer than manual close() calls.
- read(), readline(), and readlines() offer different ways to load file content.
- Looping directly over a file object is the most memory-efficient way to read large files.
- "w" mode erases existing content, while "a" mode appends without deleting anything.
- os.path.exists() lets you check whether a file exists before trying to open it.
Summary
File handling lets your Python programs save and retrieve data that outlives a single run of the script. You learned how to open files safely with the with statement, read their contents in several ways, write and append new content, and check for a file's existence before working with it.
- You can open files using open() with the correct mode.
- You understand why with is the recommended way to handle files.
- You can read, write, and append content to files.
- You are ready to learn how to handle errors gracefully with exceptions.