File Handling in Python – Saving, Reading, Updating, and Deleting External Data
In real-world programming, data rarely lives entirely inside your code. This post explores Python’s built-in file handling capabilities, covering how to save, read, update, and delete external data using text and JSON files.
Day 19 of Asabeneh Yetayeh’s 30 Days of Python introduces file handling. A built-in module in Python that helps developers work with external data.
While I would still consider myself a beginner, I’ve attempted applying this logic to a small program I made for generating passwords. This program allows users to store, update, and delete entries while generating new ones from memorable words that you provide.
The problems I encountered while learning to implement this process of reading and writing to a file were the functions. There are many options available with this, and I needed to get myself familiar with knowing how to use them.
Of course, I used a bit of AI to help me come up with the skeleton structure, but I went in and refined the code to make it my own. This is why I continue to revisit the topics until they stick with me.
In a real-world scenario, we’d probably think about the data type we’d use for the data and also what file type we need. For the purpose of being able to show that we can implement a basic function of reading and writing to a file, we’ll most likely stick to working with a normal text file (.txt).
By saving data externally—using formats such as .txt or .json—we separate program logic from program data. I need to be able to know how to create these functions in a manner that’s fit for the project I could be working with.
Opening Files and Their Modes
Python’s built-in open() function is the core module we need to get our function working. This takes two pieces of information; file path, and the mode we want the file opened in.
1
2
3
#syntax:
open('filename_and_location', 'mode')
File Modes Explained
The mode is what helps Python know what you would like to do with the file once it’s opened. You might have a program that you want to use to just read files like a PDF viewer, or you might want to append information to a file like a Microsoft Word document.
Selecting the correct mode is vital to Python, as the rest of the functions you wish to use will depend entirely on how the file is opened in or by Python. Here is a collated list of modes and what they do:
| Mode | Name | Description |
|---|---|---|
r | Read | Opens a file for reading. Raises an error if the file does not exist. (Default) |
a | Append | Opens a file for appending. Creates the file if it does not exist. |
w | Write | Opens a file for writing and overwrites existing content. Creates the file if it does not exist. |
x | Create | Creates a new file. Raises an error if the file already exists. |
t | Text | Opens the file in text mode. (Default) |
b | Binary | Opens the file in binary mode (used for images, audio, video, etc.). |
Using the syntax I provided above, Using the syntax I provided above, I can go ahead and build my function to open a file.
Defining The File Path
I didn’t originally want to include this when writing this post, but as I revised over my own work, it became more apparent that it was a subtlety I needed to include.
In my previous post, I went over regular expressions and how to use them. I also went over string escape sequences and what they are.
Depending on how you specify the file path for what you want to work on, you may have to use these methods to allow Python to read them as a normal file path.
Here is a comparison:
1
2
# Method 1:
open(r'C:\Path\To\file.txt', 'r')
1
2
# Method 2:
open("/home/sheikh/Documents/file.txt", 'r')
Method 1 could be described as a traditional approach to providing file paths. The problem we’ll find with this method is that each backslash will be recognised as a character escape sequence, which we want to avoid. It’ll think \t' is tab space` and not part of the file path.
Method 2 is more appropriate, but I’ve taken this module through ChatGPT, and it’s informed me that the correct method is to use an imported function called pathlib with the attribute Path.
Using pathlib
This is an entirely new function that I have discovered while writing this post, and it’s important that I include as much as I can about it. The reason for this is that this is supposedly the professional method used in all Python projects.
1
from pathlib import Path
This enables your program to work with different Operating Systems like Mac, Linux, and Windows without causing any disruptions, making it scalable.
This is making me think about the rest of the modules now…
This module brings in many other functions, like Change Directory, list items in a directory, remove a file, and rename files.
As I haven’t been able to fully explore this function as of writing this, I’ll include some basic examples. Once I have taken the time to learn more on this module, I’ll go on ahead and create a post for it.
| Command | What It Does | Example | Output / Benefit |
|---|---|---|---|
Path("file.txt") | Create a Path object | from pathlib import Pathpath = Path("log.txt") | Represents a file safely, works like a pointer to the file |
Path.cwd() | Get current working directory | Path.cwd() | Shows where Python is looking for files; cross-platform |
Path.home() | Get user’s home folder | Path.home() | Works on all OS; avoids typing full paths like C:/Users/... |
/ operator | Join paths safely | Path("data") / "log.txt" | Avoids slash mistakes; cross-platform |
exists() | Check if file/folder exists | path.exists() | Returns True / False; helps avoid errors |
is_file() | Check if path is a file | path.is_file() | Returns True if it’s a file, not a folder |
is_dir() | Check if path is a directory | path.is_dir() | Returns True if it’s a folder |
read_text() | Read whole file as text | path.read_text() | Shortcut instead of open/read/close |
write_text() | Write text to file | path.write_text("Hello World") | Creates file if it doesn’t exist, overwrites if it does |
touch() | Create an empty file | Path("new.txt").touch() | Quick way to make a new file |
mkdir() | Create a folder | Path("data").mkdir() | Creates folder; can use exist_ok=True to avoid errors |
unlink() | Delete a file | Path("old.txt").unlink() | Removes a file safely |
rename() | Rename or move a file | Path("old.txt").rename("new.txt") | Safe renaming/moving |
Table built with ChatGPT
This is lazy work, I know. However, I really want to get down to using the built-in functions first and then work with imported functions later.
Reading a File
Now that we’ve gained some insight into the different methods used to open a file along with the modes available, let’s use some of them.
1
open("filename.txt", 'r')
This has opened the file in read mode. We can now tell Python to read the contents and output them into our terminal.
1
2
3
4
file = open("filename.txt", 'r')
data = file.read()
print(data)
file.close() # Always look to close the file once done
We have now told Python to open the file as read and placed that in file, we’ve then poured the contents into data by using .read(), and finally, we’ve instructed Python to place the contents into the terminal.
Output:
I will not encourage others to fly. I will not encourage others to fly…
Bart Simpson — if you know, you know.
Why Closing a File Matters
If I’m honest, I’ve not really used this much throughout projects that I have made. A recommendation made by none other than ChatGPT says that we should use this where possible.
I can understand when it comes to larger systems and for scalability, rather, I keep this knowledge as useful to know when it’s required to use.
Leaving them open unnecessarily can lead to:
- Memory leaks
- Locked files
- Unexpected program behaviour
Open file → Work with file → Save changes → Close file
This again places more emphasis on thinking and being like developers to ensure the proper logical flow of a system than anything else.
Common File Methods
Hitherto, we’ve explored opening files and closing them using the correct mode. I need to learn how to process files and make changes to them as I want.
Python has many methods that we can use to read, write, and update or amend a file.
| Category | Method | What It Does | Example | Result |
|---|---|---|---|---|
| Reading | read() | Reads the entire file as a single string | f.read() | 'Hello\nWorld' |
read(n) | Reads first n characters | f.read(5) | 'Hello' | |
readline() | Reads one line | f.readline() | 'Hello\n' | |
readlines() | Reads all lines into a list | f.readlines() | ['Hello\n', 'World\n'] | |
splitlines() | Removes newline characters | f.read().splitlines() | ['Hello', 'World'] | |
| Writing | write() | Writes a string to a file | f.write('Hello') | File updated |
writelines() | Writes a list of strings | f.writelines(lines) | Writes as-is | |
| Control | seek() | Moves cursor position | f.seek(0) | Reset pointer |
tell() | Returns cursor position | f.tell() | 5 | |
truncate() | Cuts file at cursor | f.truncate() | File shortened | |
| Safety | close() | Closes file | f.close() | File released |
with open() | Auto-closes file | with open() as f: | Safer handling |
Note: Opening a file does nothing on its own. Methods such as
.read()or.write()are required to interact with its contents.
Using with open() (Best Practice)
Earlier, I mentioned that it’s important to close a file that you are working with once your program has completed its actions.
Python provides a with function that only keeps the file open while you perform some functions and then closes it automatically.
It also refactors code by placing the open file into a variable on load using as, removing the need for creating a variable and then placing the open file there.
1
2
3
with open('filename.txt', 'r') as f:
txt = f.read()
print(txt)
Output:
I will not encourage others to fly. I will not encourage others to fly. I will not encourage others to fly…
Reading and Writing Together
I’ll now show you how to append information to a file. There are different approaches you can take with this; one method will overwrite the complete file, another will append the changes to the end of the file.
For this demonstration, we’ll use a to append to the file at the end, as this is usually what we would do.
1
2
3
4
5
6
7
8
9
def write_to_file(filename_and_path, new_text):
with open(filename_and_path, 'a') as file:
file.write(new_text)
with open(filename_and_path, 'r') as file:
data = file.read()
print(data)
write_to_file('filename.txt', 'Hello, this is appending text.')
Output:
I will not encourage others to fly. I will not encourage others to fly…Hello, this is appending text.
If we opened the file as w or write and then appended some information, it would rewrite over the file and the output would be different.
1
2
3
4
5
6
7
8
9
def write_to_file(filename_and_path, new_text):
with open(filename_and_path, 'w') as file:
file.write(new_text)
with open(filename_and_path, 'r') as file:
data = file.read()
print(data)
write_to_file('filename.txt', 'Hello, this is appending text.')
Output:
Hello, this is appending text.
Daily Summary
Quite frankly, this topic was easier to digest than some of the more advanced topics that I’ve covered. It makes me feel as though I am ready to start coding in Python for larger projects but I do feel like I’ve got a “code block”. A lot of the functions and modules discussed in this chapter are all easier to remember as they work like a mnemonic making coding really good with it too.
I get that most of the information discussed were all around using a .txt file which is a little unfair; however, using .json files are more toward specific applications that’ll use lists or dictionaries as storage. I believe that the reason why I have a roadblock in coding is because I am not actively creating projects.
I will sit and just research countlessly, watch videos, do some tutorials. While this is really good, it prevents me from applying any of my newly found knowledge to help retain the information and gain a deeper insight.
