Search code examples
pythonreadlines

How to open a file and change a line


I've looked at loads of threads on this but cant find the right answer:

I'm a bit new to python. Im opening a file in python, inserting one line before the beginning line and one before the last line and then reconstructing all the lines into a string variable at the end.

Heres the function Im trying to run on the opened file. This changes all lines where mode="0" to mode="1" or vice versa.

def Modes(file, mode):
    endstring = ''
    if(mode == 1):
        mode0 = 'mode="0"'
        mode1 = 'mode="1"'
    else:
        mode0 = 'mode="1"'
        mode1 = 'mode="0"'   
    for line in iter(file):
        if 'Modes' in line:
            line = line.replace(mode0,mode1)
        endstring += line
    return endstring

So I try the following:

  mode = 1
  input_file = open("c:\myfile.txt")
  input_file.readlines()
  lengthlines = len(input_file)
  #insert line at position 1
  input_file.insert(1,'<VARIABLE name="init1" />')
  #insert line at last line position - 1
  input_file.insert(lengthlines,'<VARIABLE name="init2" />')
  #join the lines back up again
  input_file = "".join(input_file)
  #run the modes function - to replace all occurrences of mode=x
  finalfile = Modes(input_file,mode)
  print finalfile

And then Im getting the error, "object of type file, has no "len()"" and general object/list errors.

It seems Im getting objects/lists etc mixed up but im not sure where - would be grateful for any assistance - cheers


Solution

  • input_file.readlines() returns the content but does not assign it to input_file. You'll have to assign the return value of the call to a variable, like so:

    file_content = input_file.readlines()
    

    and then pass that to len()

    lengthlines = len(file_content)
    

    EDIT: solving the issue with len() leads to further exceptions. This should roughly do what you want:

    mode = 1
    with open("c:\myfile.txt") as input_file:
        file_content = list(input_file.readlines())
    file_content.insert(0,'<VARIABLE name="init1" />')
    file_content.append('<VARIABLE name="init2" />')
    finalfile = Modes(file_content,mode)
    print finalfile
    

    You might have to alter your string concatenation in the function if you want to stick with several lines.

        endstring += line + '\n'
    return endstring.rstrip('\n')
    

    This does not yet write the new content back to the file though.

    EDIT2: And it is always good practice to close the file when you are done with it, therefore I updated the above to use a context manager that takes care of this. You could also explicitly call input_file.close() after you are finished.