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.
A file is a named set of data on disk. Let's go through it in order: how to open a file, read from it, write to it, and why it matters to close it.
Basic File Operations
In Python, working with files usually includes the following steps:
- Opening a file — specify the file and the mode of working with it
- Reading or writing — perform the necessary operations with the file
- Closing the file — free up system resources
Let's consider each of these steps in more detail.
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.
Here are the basic file opening modes:
Examples of opening files in different modes:
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()
Note: 'r' requires the file to already exist — otherwise you get a FileNotFoundError. 'w' is the opposite: if the file doesn't exist it creates it, and if it does, it wipes the old contents.
Reading from a File
After opening a file, its contents can be read in several ways. In the examples below the file is opened with with open(...) as ... — a safe way that closes the file for you at the end; we'll cover it shortly, for now just read it as "open the file for the duration of the block".
Reading the entire file
Python 3.13# Let's create a test file with open('sample.txt', 'w') as f: f.write("First line\nSecond line\nThird line") # Reading the entire file at once with open('sample.txt', 'r') as file: content = file.read() print("File contents:")File contents:print(content)First line Second line Third line
Reading a file line by line
Python 3.13# Reading a file line by line using a loop with open('sample.txt', 'r') as file: print("Reading line by line:")Reading line by line:for line in file: print(f" Line: {line.strip()}")Line: First line Line: Second line Line: Third line
Reading a specific number of characters
Python 3.13# Reading a specific number of characters with open('sample.txt', 'r') as file: first_10_chars = file.read(10) print(f"First 10 characters: {first_10_chars}")First 10 characters: First line# Reading the next 10 characters next_10_chars = file.read(10) print(f"Next 10 characters: {next_10_chars}")Next 10 characters: Second li
Reading all lines into a list
Python 3.13# Reading all lines into a list with open('sample.txt', 'r') as file: lines = file.readlines() print(f"List of lines: {lines}")List of lines: ['First line\n', 'Second line\n', 'Third line']
Writing to a File
Writing data to a file can also be done in different ways:
Writing a string
Python 3.13# Writing a string to a file with 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') # Alternative way: using writelines() with open('lines2.txt', 'w') as file: # Don't forget to add newline characters file.writelines([line + '\n' for line in lines]) # Let's check the second file with open('lines2.txt', 'r') as file: content = file.read() print("Contents of lines2.txt:")Contents of lines2.txt:print(content)First line Second line Third line
Appending data to the end of a file
Python 3.13# Appending data to the end of a file (mode 'a') with open('output.txt', 'a') as file: file.write("\nThis line was added later.") # Let's check the result with open('output.txt', 'r') as file: content = file.read() print("File contents after appending:")File contents after appending:print(content)Hello, world! Python is a great programming language. This line was added later.
The with Context Manager
In all the examples above the file was opened with with open(...) as file:. Now it's time to explain this construct.
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
Exception Handling When Working with Files
Various errors can occur when working with files:
- The file doesn't exist
- Insufficient permissions to access the file
- The disk is full
- Etc.
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!") except PermissionError: print("Error: Insufficient permissions to access the file!") except Exception as e: print(f"An error occurred: {e}")Error: File not found!
Additional File Operations
Python provides many additional capabilities for working with files:
Moving the Pointer
Python 3.13# A small file for the example with open('demo.txt', 'w') as file: file.write("Hello, world!") # seek() moves the pointer to a given position with open('demo.txt', 'r') as file: print(file.read(5)) # first 5 charactersHellofile.seek(0) # back to the start print("After seek(0):", file.read(5))After seek(0): Hellofile.seek(7) # jump to position 7 print("After seek(7):", file.read(5))After seek(7): world
Here the text is English, so the position matches the character number. A subtlety: seek and tell actually count the position in bytes. For Latin letters one character is one byte, but a character outside ASCII — a Cyrillic letter in UTF-8, say — takes two bytes, so for such text the position numbers shift.
Getting the Current Position
Python 3.13# tell() returns the current pointer position with open('demo.txt', 'r') as file: print(f"Initial position: {file.tell()}")Initial position: 0file.read(5) print(f"After reading 5 characters: {file.tell()}")After reading 5 characters: 5
Working with File Paths
When working with files, it's important to specify paths correctly. Python provides the os.path module and the pathlib module to make working with paths easier:
In the sandbox the current directory is /home/pyodide; on your own computer the path will differ.
Python 3.13import os # Current working directory current_dir = os.getcwd() print(f"Current directory: {current_dir}")Current directory: /home/pyodide# Joining paths (correctly handling separators) data_file = os.path.join(current_dir, 'data', 'info.txt') print(f"Path to file: {data_file}")Path to file: /home/pyodide/data/info.txt# Checking if a file exists sample_exists = os.path.exists('sample.txt') print(f"File sample.txt exists: {sample_exists}")File sample.txt exists: True# Getting the filename and extension filename = "path/to/document.pdf" basename = os.path.basename(filename) name, ext = os.path.splitext(basename) print(f"Filename: {name}, extension: {ext}")Filename: document, extension: .pdf
A more modern approach using pathlib:
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# Checking if a file exists sample_path = Path('sample.txt') print(f"File sample.txt exists: {sample_path.exists()}")File sample.txt exists: True# 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
Understanding Check
Which code correctly opens a file for writing and appends a string to the end of the file?
In future lessons, we'll delve deeper into working with specific file types, such as text files, CSV, JSON, and others.
