3

How to edit an INI file in Python 2.7

I am trying to edit an INI config file that already has the Sections and Options I need. However I need to update the values depending on a checkboxlist in wxPython. Currently everything is working :), but I feel like there is a better way. Here is part of the function snippet I'm using.

def read_or_write_file(self, file, section, passed_option = None,
                      value = None, read = True):

    if read:
        with open(file) as configfile:
            config = ConfigParser.RawConfigParser()
            config.readfp(configfile)
            options = config.options(section)

            for option in options:
                file_settings[option] = config.get(section, option)

    else:
        with open(file, 'r+') as configfile:
            config = ConfigParser.RawConfigParser()

            config.readfp(configfile)
            config.set(section, passed_option, value)

        with open(file, 'r+') as configfile:
            config.write(configfile)

This works exactly how I want it to, I tell it what I want to read or write and it works. However the else: part where I write to the file seems strange. I have to edit config first then rewrite everything in the configfile.

Is there a way to only rewrite the value I am changing?

This is my first question, so if I forgot to mention something let me know.

Also a points of information: - I have looked at all of the documentation or at least what I could find - This is similar but not exactly what I need How to read and write INI file with Python3?

Community
  • 1
  • 1

2 Answers2

2

"Is there a way to only rewrite the value I am changing?" No, because it's a text file. You can only do a selective rewrite when you know that the thing you're writing will be exactly the same length as the thing you're replacing. That's not generally the case with text files, and they're almost never treated that way.

I'd do only a small re-organization of this function to remove redundancy:

def read_or_write_file(self, file, section, passed_option = None,
                      value = None, read = True):

    config = ConfigParser.RawConfigParser()
    with open(file) as configfile:
        config.readfp(configfile)    

    if read:
        options = config.options(section)

        for option in options:
            file_settings[option] = config.get(section, option)

    else:
        config.set(section, passed_option, value)

        with open(file, 'w') as configfile:
            config.write(configfile)
William McBrine
  • 2,166
  • 11
  • 7
  • Okay that makes sense, I did not realize that you can't change a text file like that. That would explain why I was having issues getting it to work. I do have another question then. Does the amount of time it takes to rewrite the whole text file really matter? Or should I figure out a different way to implement what I am trying to do? – Bradley Collins Jul 25 '14 at 15:49
  • A typical .ini file is very small, so I wouldn't worry about the time spent writing it out, no. – William McBrine Jul 26 '14 at 05:35
0

It's not possible in general, because of the way files work. You cannot "insert" bytes into a file - you always overwrite the current content.

It would be possible to rewrite only parts of a file only with the content of the same length, e.g. when you would want to change a string "XXX" to "YYY". But it's quite a common practice to just not worry about it, and serialize such files as a whole every time it's needed.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130