Sign in to your Python Morsels account to save your screencast settings.
Don't have an account yet? Sign up here.
Let's talk about file modes in Python.
The default mode when you open a file is r
or rt
for read mode:
>>> with open("my_file.txt") as f:
... print(f.mode)
...
r
You can specify that explicitly by specifying a mode
keyword argument:
>>> with open("my_file.txt", mode="rt") as f:
...
When you open a file in read mode, you can use the read
method of the file object to read the entire file at once into a string (see reading from a text file in Python):
>>> with open("my_file.txt", mode="rt") as f:
... contents = f.read()
...
>>> type(contents)
<class 'str'>
>>> contents
'This is my file\nTODO add more to file\n'
Or you can loop over the file object to read your file line by line:
>>> with open("my_file.txt", mode="rt") as f:
... for line in f:
... if "TODO" in line:
... print(f"Found TODO in {f.name}")
...
Found TODO in my_file.txt
If you'd like to write to a file, you'll want to open it in write mode, that is w
or wt
mode.
When opening a file in write mode, you can write to the file but can't read from it.
Once you've opened a file in write mode you can call the write
method to write to it:
>>> with open("message.txt", mode="wt") as f:
... f.write("Hello world!\n")
...
13
If this file (message.txt
) had already existed, we would've completely overwritten the file.
When you open a file in write mode Python will truncate that file, meaning it completely clears out the contents of the file.
If you want to open a file for writing while making sure that the file doesn't exist yet, you can use x
or xt
mode, for exclusive create mode.
Here we're creating a new file called brand_new_file.txt
:
>>> with open("brand_new_file.txt", mode="xt") as f:
... f.write("Hello world!\n")
...
13
If we try to do that again, we'll get a FileExistsError
because the file already exists:
>>> with open("brand_new_file.txt", mode="xt") as f:
... f.write("Hello world!\n")
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileExistsError: [Errno 17] File exists: 'brand_new_file.txt'
Create mode can be helpful for ensuring you're not overwriting an existing file.
If you'd like to add to the end of a file, you can use the mode a
or at
for append mode:
>>> with open("my_file.txt", mode="at") as f:
... f.write("Adding more to the end of the file.\n")
...
36
This works pretty much the same way as write mode, except that every write
method call will always write to the end of the file.
Before we appended, our my_file.txt
file looked like this:
This is my file
TODO add more to file
But after appending, there's now a third line:
This is my file
TODO add more to file
Adding more to the end of the file.
+
modes)There are other file modes, but they're all a little bit uncommon.
The other modes are +
modes which allow us to read and write at the same time.
The most common of these is r+
mode:
>>> with open("my_file.txt", mode="r+") as f:
... old_contents = f.read()
... f.seek(0)
... f.write("Hello!\n")
... f.write("\nThe old file contents were:\n\n")
... f.write(old_contents)
...
0
7
30
74
In our code above, we read from our file, seeked back to the beginning of the file, wrote some things to the beginning, and then wrote the original contents back to the end.
We've done something similar to a reverse append here because we added text to the very beginning of our file:
Hello!
The old file contents were:
This is my file
TODO add more to file
Adding more to the end of the file.
An alternative to using r+
mode would have been opening our file, reading from it, closing it, and then opening our file again and writing the new contents to it.
So the usual file modes you'll use are: read mode, write mode, append mode, and exclusive create mode.
Features | r |
w |
a |
x |
---|---|---|---|---|
allows read | ✔️ | |||
allows write | ✔️ | ✔️ | ✔️ | |
must exist | ✔️ | |||
must not exist | ✔️ | |||
positioned at start | ✔️ | ✔️ | ✔️ | |
positioned at end | ✔️ | |||
always writes to end | ✔️ |
You can see all of their features in the above table.
There are also four +
modes that correspond to the four modes above. These modes all allow for reading and writing at the same time.
Features | r+ |
w+ |
a+ |
x+ |
---|---|---|---|---|
allows read | ✔️ | ✔️ | ✔️ | ✔️ |
allows write | ✔️ | ✔️ | ✔️ | ✔️ |
must exist | ✔️ | |||
must not exist | ✔️ | |||
truncates (clear file) | ✔️ | |||
positioned at start | ✔️ | ✔️ | ✔️ | |
positioned at end | ✔️ | |||
always writes to end | ✔️ |
You probably don't want to use any of these +
modes.
But if you do use any of these it will probably be r+
mode because w+
, a+
, and x+
mode are all even weirder than r+
mode.
All of the above modes are text mode by default, so there's an implicit t
after all of them (e.g. r
mode is the same as rt
mode).
But you could instead add a b
to your mode to open a file in binary mode (rb
for binary read mode):
>>> with open("my_file.txt", mode="rb") as f:
... data = f.read()
...
>>> type(data)
<class 'bytes'>
When opening a file in binary mode, we'll get back a bytes
object when we read from our file (rather than the string we usually get).
You probably don't want to open a file in binary mode unless you're doing something pretty low level because strings are a lot easier to work with than bytes.
When you open a file in Python, you'll probably open that file in one of the following modes:
There are other modes besides the above four, but they're a little bit uncommon to see.
Need to fill-in gaps in your Python skills?
Sign up for my Python newsletter where I share one of my favorite Python tips every week.
Sign in to your Python Morsels account to track your progress.
Don't have an account yet? Sign up here.