File Handling in Python
On this page
Opening and Closing FilesUsing Context Managers (with)Checking File PropertiesReading Text FilesWriting Text FilesAppending to a FileReading Files Line by LineHandling Exceptions When Working with FilesConclusionFile handling is the practical foundation for working with data outside your program. Whether you read input files, write analysis results, or store logs and configuration settings, Python gives you straightforward tools to open, read, write, and manage files safely.
Before exploring structured formats like CSV, JSON, and binary serialization, it’s important to understand how Python handles plain text files: how to open them, how to read and write their contents, and how to ensure they close correctly.
Use a new practice folder. Before running the examples, create notes.txt with the two lines First note. and Second note., story.txt with A short story., and large_dataset.txt with the two lines record one and record two. End each line with a newline. Leave config.ini absent to test the missing-file path. These small fixtures make the output reproducible.
Opening and Closing Files
Python opens files using the built-in open() function. Its first argument is a file name or path; an optional second argument supplies the mode:
- the file name or path
- the mode, which tells Python how the file should be accessed
Common modes include: - "r" — read (default) - "w" — write (overwrites existing content) - "a" — append - "rb" /"wb" — binary read/write
Before reading or writing, you must open the file; once the work is done, you must close it.
Example: Opening a File in Read Mode
f = open("notes.txt", "r", encoding="utf-8")
print(f)
f.close()Output
<_io.TextIOWrapper name='notes.txt' mode='r' encoding='utf-8'>
If notes.txt exists,open() connects to it and returns a file object. The close() call releases system resources. Forgetting to close a file is a common beginner’s mistake, and Python provides a safer alternative.
Using Context Managers (with)
In real software, anything can go wrong while reading or writing: the file might be missing, corrupted, or locked. If an error occurs, a manually opened file may remain unclosed—potentially corrupting data.
To avoid this, Python offers the with statement. It opens the file at the start of the block and always closes it afterward, even if an exception is raised.
Example: Reading a File Safely
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)Output
First note.
Second note.
with ensures the file closes automatically. Inside the block, the file is open; once the block ends, Python closes it—no matter what happened. This pattern is the recommended way to handle files.
Checking File Properties
Once a file is open, Python exposes useful metadata. You can inspect the file’s name, the mode used to open it, and whether the file is currently open or already closed.
Example: Inspecting a File Object
with open("notes.txt", "r", encoding="utf-8") as f:
print("Filename:", f.name)
print("Mode:", f.mode)
print("Is closed?", f.closed)
print("Is closed after block?", f.closed)Output
Filename: notes.txt
Mode: r
Is closed? False
Is closed after block? True
f.nameprints the file name.f.modeshows"r"here, because we opened the file in read mode.f.closedisFalseinside the block and True afterward.
This is helpful when diagnosing and debugging problems in file-heavy workflows.
Reading Text Files
The main reading methods are:
read()— load the entire file as a single stringreadline()— read one line at a timereadlines()— return all lines as a list
Example: Reading a File with read()
Suppose you want to display the contents of a text file to the user:
with open("story.txt", "r", encoding="utf-8") as f:
text = f.read()
print(text)Output
A short story.
read() loads the full content into memory.
For very large files, you might prefer line-by-line reading to avoid excessive memory usage.
Writing Text Files
Writing uses the "w" or "a" modes:
"w"overwrites the file or creates it if missing"a"appends to the end
Example: Writing New Content
with open("summary.txt", "w", encoding="utf-8") as f:
f.write("Project Summary\n")
f.write("================\n")
f.write("All tasks completed successfully.\n")These writes produce no visible output. Because we used "w", any existing content is replaced. This is ideal for generating reports or exporting results.
Appending to a File
Appending is useful for logs or history tracking. Each run can add new entries without deleting earlier records.
Example: Adding Log Entries
with open("app.log", "a", encoding="utf-8") as f:
f.write("User logged in\n")
f.write("User opened settings\n")These writes produce no visible output. New log entries are added at the end, preserving the previous content.
Reading Files Line by Line
Reading line by line can reduce memory use when processing large text files, such as logs or transcripts.
Example: Efficient Line Processing
with open("large_dataset.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())Output
record one
record two
This approach keeps memory usage low by reading only one line at a time—ideal for files that may be several gigabytes.
Handling Exceptions When Working with Files
Sometimes files are missing or inaccessible. Rather than crashing, programs should handle such cases gracefully.
Example: Safe Reading with Error Handling
try:
with open("config.ini", "r", encoding="utf-8") as f:
content = f.read()
print(content)
except FileNotFoundError:
print("Error: The configuration file is missing.")Output
Error: The configuration file is missing.
tryexecutes the file operation.excepthandles common issues, such as missing files.- The
withblock closes the file if opening succeeded. If opening failed, there is no file object to close.
Use with for the resource and try for the failure you can handle; they solve different parts of the problem.
Conclusion
File handling gives your programs persistence. It allows them to load data from the outside world, save their results, maintain logs, and process text-based datasets reliably. With these foundational tools—open(), context managers, reading and writing methods, and basic error handling—you are now ready to explore more advanced forms of data exchange.
In the next section, we move from raw text files to serialization, where data is stored and exchanged in structured formats such as CSV, JSON, and Python’s own binary representations.