Working with Files in Python
Any variable lives only while the program is running: close it, and your to-do list, the score you racked up, your saved settings are gone. To make data survive a restart, you write it to a file on disk and read it back next time. That's what notes, game saves, report exports (almost any application) rest on.
Opening Files
To open a file in Python, the open() function is used. It takes at least two parameters: the path to the file and the opening mode.
The mode is a short string that answers "what are we going to do with this file". You pick one of three:
Let's see the two most common modes in action:
Python 3.13# 'w' creates the file (or overwrites it) and opens it for writing file = open('notes.txt', 'w') file.write("Buy milk") file.close() # 'r' opens an existing file for reading file = open('notes.txt', 'r') print(file.read())Buy milkfile.close()
'w' deserves a separate warning: it wipes the old contents silently, with no confirmation. Open a file full of important data with 'w' instead of 'a', and the data is gone. 'r' is the opposite: it requires the file to already exist, and if it doesn't, Python stops the program with a FileNotFoundError.
The with Context Manager
In the example above, close() was called after the work with the file was done. Let's see why that call is needed and why real code almost never writes it.
An open file has to be closed: while it's open it holds system resources, and written data may not reach the disk until it's closed. You can close it manually:
Python 3.13file = open('example.txt', 'w') file.write("Example text") file.close()
The catch is that it's easy to forget close(). And if something goes wrong between opening and closing and the program is interrupted, close() is never reached, and the file stays open.
The with construct takes this off your hands: it closes the file when the block ends, no matter the outcome.
Python 3.13with open('example.txt', 'w') as file: file.write("Example text") # the file is already closed here automatically print("File automatically closed after the with block")File automatically closed after the with block
Reading from a File
After opening a file, its contents can be read in several ways.
In all the examples below, a sample.txt file with three lines sits next to the program.
Reading the entire file
1with open('sample.txt', 'r') as file:2 content = file.read()3 4print(content)5 Run main.py, and the output is:
First line Second line Third line
Reading a file line by line
1with open('sample.txt', 'r') as file:2 for line in file:3 print(f"Line: {line.strip()}")4 Run main.py, and the output is:
Line: First line Line: Second line Line: Third line
Reading all lines into a list
for line in file takes lines one at a time and never holds the whole file in memory. That's the default choice, especially for large files. But sometimes you need all the lines at once: to count them, to reach the fifth one, to sort them. That's what readlines() is for; it returns an ordinary list:
1with open('sample.txt', 'r') as file:2 lines = file.readlines()3 4print(lines)5 Run main.py, and the output is:
['First line\n', 'Second line\n', 'Third line']
Notice the \n at the end of each element: readlines() cuts the file at the line breaks but doesn't throw them away. That's why line.strip() showed up in the example above: print adds its own line break on top of the one that came from the file, and without strip() you'd get blank lines in between.
Writing to a File
There are several ways to write data to a file:
Writing a string
Python 3.13with open('output.txt', 'w') as file: file.write("Hello, world!\n") file.write("Python is a great programming language.") # Let's check what was written with open('output.txt', 'r') as file: content = file.read() print("File contents after writing:")File contents after writing:print(content)Hello, world! Python is a great programming language.
Writing multiple lines
Python 3.13# Writing a list of strings to a file lines = ["First line", "Second line", "Third line"] with open('lines.txt', 'w') as file: for line in lines: file.write(line + '\n') # Let's check what was written with open('lines.txt', 'r') as file: content = file.read() print("Contents of lines.txt:")Contents of lines.txt:print(content)First line Second line Third line
Appending data to the end of a file
Next to the program sits output.txt with two lines — the 'a' mode will append to its end without erasing anything:
1with open('output.txt', 'a') as file:2 file.write("3This line was added later.")4 5with open('output.txt', 'r') as file:6 print(file.read())7 Run main.py, and the output is:
Hello, world! Python is a great programming language. This line was added later.
Exception Handling When Working with Files
Various errors can occur when working with files: the file isn't there, you don't have permission to access it, the disk is full.
Catching such errors and reacting to them is the job of the try/except construct (it has its own lesson later in the course). Here it's enough to see it in action on files: the try block attempts the operation, and except catches a specific error if it happened.
Python 3.13# Handling possible errors when opening a file try: with open('non_existent_file.txt', 'r') as file: content = file.read() except FileNotFoundError: print("Error: File not found!")Error: File not found!
Working with File Paths
So far we've written file names plainly: open('notes.txt'). Python looks for such a file in the current directory, the one the program was started from.
If the file sits in a neighbouring folder, you need a path. Gluing one out of strings is risky: on macOS and Linux the parts are separated by /, on Windows by \. A path written by hand breaks as soon as the code moves to another system.
So paths are assembled with the pathlib module from the standard library.
In pathlib a path is an object rather than a string: parts are joined with the / operator, and the name, the extension and the existence check live right on the object. Such code reads closer to how a path actually looks.
In the sandbox the current directory is /home/pyodide; on your own computer the path will differ.
Python 3.13from pathlib import Path # Current directory current_path = Path.cwd() print(f"Current directory: {current_path}")Current directory: /home/pyodide# Creating a path data_file = current_path / 'data' / 'info.txt' print(f"Path to file: {data_file}")Path to file: /home/pyodide/data/info.txt# Getting the filename and extension document_path = Path("path/to/document.pdf") print(f"Filename: {document_path.stem}, extension: {document_path.suffix}")Filename: document, extension: .pdf
Checking existence is the exists() method: it answers whether a real file is at that path. Below, sample.txt sits next to the program and missing.txt does not:
1from pathlib import Path2 3print(Path('sample.txt').exists())4print(Path('missing.txt').exists())5 Run main.py, and the output is:
True False
Understanding Check
What happens to the contents if you open an existing file in 'w' mode?
In future lessons, we'll delve deeper into working with specific file types, such as text files, CSV, JSON, and others.
