From the doc,

Modes ‘r+’, ‘w+’ and ‘a+’ open the file for updating (note that ‘w+’ truncates the file). Append ‘b’ to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that don’t have this distinction, adding the ‘b’ has no effect.

and here

w+ : Opens a file for both writing and reading. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing.

But, how to read a file open with w+?

Here is a list of the different modes of opening a file:

  • r

    Opens a file for reading only. The file pointer is placed at the beginning of the file. This is the default mode.

  • rb

    Opens a file for reading only in binary format. The file pointer is placed at the beginning of the file. This is the default mode.

  • r+

    Opens a file for both reading and writing. The file pointer will be at the beginning of the file.

  • rb+

    Opens a file for both reading and writing in binary format. The file pointer will be at the beginning of the file.

  • w

    Opens a file for writing only. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing.

  • wb

    Opens a file for writing only in binary format. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing.

  • w+

    Opens a file for both writing and reading. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing.

  • wb+

    Opens a file for both writing and reading in binary format. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing.

  • a

    Opens a file for appending. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing.

  • ab

    Opens a file for appending in binary format. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing.

  • a+

    Opens a file for both appending and reading. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing.

  • ab+

    Opens a file for both appending and reading in binary format. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing.

All file modes in Python

  • r for reading
  • r+ opens for reading and writing (cannot truncate a file)
  • w for writing
  • w+ for writing and reading (can truncate a file)
  • rb for reading a binary file. The file pointer is placed at the beginning of the file.
  • rb+ reading or writing a binary file
  • wb+ writing a binary file
  • a+ opens for appending
  • ab+ Opens a file for both appending and reading in binary. The file pointer is at the end of the file if the file exists. The file opens in the append mode.
  • x open for exclusive creation, failing if the file already exists (Python 3)

Let’s say you’re opening the file with a with statement like you should be. Then you’d do something like this to read from your file:

with open('somefile.txt', 'w+') as f:
    # Note that f has now been truncated to 0 bytes, so you'll only
    # be able to read data that you write after this point
    f.write('somedata\n')
    f.seek(0)  # Important: return to the top of the file before reading, otherwise you'll just read an empty string
    data = f.read() # Returns 'somedata\n'

Note the f.seek(0) — if you forget this, the f.read() call will try to read from the end of the file, and will return an empty string.

r for read

w for write

r+ for read/write without deleting the original content if file exists, otherwise raise exception

w+ for delete the original content then read/write if file exists, otherwise create the file

For example,

>>> with open("file1.txt", "w") as f:
...   f.write("ab\n")
... 
>>> with open("file1.txt", "w+") as f:
...   f.write("c")
... 

$ cat file1.txt 
c$
>>> with open("file2.txt", "r+") as f:
...   f.write("ab\n")
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'file2.txt'

>>> with open("file2.txt", "w") as f:
...   f.write("ab\n")
... 
>>> with open("file2.txt", "r+") as f:
...   f.write("c")
... 

$ cat file2.txt 
cb
$

Both seems to be working same but there is a catch.

r+ :-

  • Open the file for Reading and Writing
  • Once Opened in the beginning file pointer will point to 0
  • Now if you will want to Read then it will start reading from beginning
  • if you want to Write then start writing, But the write process will begin from pointer 0. So there would be overwrite of characters, if there is any
  • In this case File should be present, either will FileNotFoundError will be raised.

w+ :-

  • Open the file for Reading and Writing
  • If file exist, File will be opened and all data will be erased,
  • If file does not exist, then new file will be created
  • In the beginning file pointer will point to 0 (as there is not data)
  • Now if you want to write something, then write
  • File pointer will be Now pointing to end of file (after write process)
  • If you want to read the data now, seek to specific point. (for beginning seek(0))

So, Overall saying both are meant to open the file to read and write but difference is whether we want to erase the data in the beginning and then do read/write or just start as it is.

abc.txt – in beginning

1234567
abcdefg
0987654
1234

Code for r+

with open('abc.txt', 'r+') as f:      # abc.txt should exist before opening
    print(f.tell())                   # Should give ==> 0
    f.write('abcd')                   
    print(f.read())                   # Pointer is pointing to index 3 => 4th position
    f.write('Sunny')                  # After read pointer is at End of file

Output

0
567
abcdefg
0987654
1234

abc.txt – After Run:

abcd567
abcdefg
0987654
1234Sunny

Resetting abc.txt as initial

Code for w+

with open('abc.txt', 'w+') as f:     
    print(f.tell())                   # Should give ==> 0
    f.write('abcd')                   
    print(f.read())                   # Pointer is pointing to index 3 => 4th position
    f.write('Sunny')                  # After read pointer is at End of file

Output

0


abc.txt – After Run:

abcdSunny

The file is truncated, so you can call read() (no exceptions raised, unlike when opened using ‘w’) but you’ll get an empty string.

I suspect there are two ways to handle what I think you’r trying to achieve.

1) which is obvious, is open the file for reading only, read it into memory then open the file with t, then write your changes.

2) use the low level file handling routines:

# Open file in RW , create if it doesn't exist. *Don't* pass O_TRUNC
 fd = os.open(filename, os.O_RDWR | os.O_CREAT)

Hope this helps..

Actually, there’s something wrong about all the other answers about r+ mode.

test.in file’s content?

hello1
ok2
byebye3

And the py script’s :

with open("test.in", 'r+')as f:
    f.readline()
    f.write("addition")

Execute it and the test.in‘s content will be changed to :

hello1
ok2
byebye3
addition

However, when we modify the script to :

with open("test.in", 'r+')as f:
    f.write("addition")

the test.in also do the respond:

additionk2
byebye3

So, the r+ mode will allow us to cover the content from the beginning if we did’t do the read operation. And if we do some read operation, f.write()will just append to the file.

By the way, if we f.seek(0,0) before f.write(write_content), the write_content will cover them from the positon(0,0).

Here is the list might be helpful

Character Meaning

‘r’ – open for reading (default)

‘w’ – open for writing, truncating the file first

‘x’ – open for exclusive creation, failing if the file already exists

‘a’ – open for writing, appending to the end of the file if it exists

‘b’ – binary mode

‘t’ – text mode (default)

‘+’ – open for updating (reading and writing)

The default mode is ‘r’ (open for reading text, synonym of ‘rt’). Modes ‘w+’ and ‘w+b’ open and truncate the file. Modes ‘r+’ and ‘r+b’ open the file with no truncation.

Reference:https://docs.python.org/3/library/functions.html#open

I was sooo confusing too… But may be my answer will help someone.
I assume that you want to leverage the ability of ‘w+’ mode to create the file if it doesn’t exist.

Indeed, only w, w+, a, a+ can create if the file doesn’t exist.

But if you need to read the data of the file (the scenario when the file with data did exist) you can’t do it with w+ out of the box because it truncates the file. Oops, you didn’t mean that!

So, probably, your best friend would be a+ with file.seek(0):

with open('somefile.txt', 'a+') as f:
    f.seek(0)
    for line in f:
        print(f.readline())

As mentioned by h4z3,
For a practical use,
Sometimes your data is too big to directly load everything, or you have a generator, or real-time incoming data, you could use w+ to store in a file and read later.