Using 'r+' mode to overwrite a line in a file with another line of the same length
Question: I have a file called `vegetables`:

> carrots  
>  apples_  
>  cucumbers

What I want to do is open the file in python, and modify it in-place, without
overwriting large portions of the file. Specifically, I want to overwrite
`apples_` with `lettuce`, such that the file would look like this:

> carrots  
>  lettuce  
>  cucumbers

To do this, I've been told to use `'r+'` mode. However, I don't know how to
overwrite that line in place. Is that possible? All the solutions I am
familiar with involve caching the entire file, and then overwriting the entire
file, for a small amendment. Is this really the best option?

**Important note** : the replacement line is always the same length as the
original line.

For context: I'm not really concerned with a file on vegetables. Rather, I
have a textfile of about 400 lines to which I need to make revisions roughly
every two minutes. I have a script to do this, but I want to do it more
efficiently.


Answer: an answer that works with your example

    
    
    with open("vegetables","r+") as t:
      data = t.read()
      t.seek(data.index("apples_"))
      t.write("lettuce")
    

although, it might not be worth it to complicate things like this,

it's fine to just read the entire file, and then overwriting the entire file,
you aren't going to save much by doing something like my example

NOTE: this only works if it has the exactly the same length as the original
text you are replacing

edit1: a (possibly bad) example to replace all match:

    
    
    import re
    
    with open("test","r+") as t:
      data = t.read()
      for m in re.finditer("apples_", data):
        t.seek(m.start())
        t.write("lettuce")
    

edit2: something a little more complex using closure so that it can check for
multiple words to replace

    
    
    import re
    
    def get_find_and_replace(f):
        """f --> a file that is open with r+ mode"""
        data = f.read()
        def find_and_replace(old, new):
            for m in re.finditer(old, data):
                f.seek(m.start())
                f.write(new)
        return find_and_replace
    
    with open("test","r+") as f:
      find_and_replace = get_find_and_replace(f)
      find_and_replace("apples_","lettuce")
      #find_and_replace(...,...)
      #find_and_replace(...,...)
    

