Only save config if changed

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Only save config if changed



Is it possible to add a check which discards a pending config change when the resulting config would be the same even tho the lines moved may have moved?



I am asking because in some scripts i save the config everytime i close some application and when i'm commiting my folder i always get stuff like this also i think it's unneccessary I/O load.



These are my loadCfg and saveCfg functions:


# I/O #
def loadCfg(path, cfg):
"""
:param path:
:param cfg:
"""
if not os.path.isfile(path) or os.path.getsize(path) < 1:
saveCfg(path, cfg)
cfg = cfg.read(path, encoding='utf-8')

def saveCfg(path, cfg):
"""
:param path:
:param cfg:
"""
with open(path, mode='w', encoding="utf-8") as cfgfile:
cfg.write(cfgfile)





I presume the cfg objects are configparser.ConfigParser objects from the standard library?
– Martin Ueding
Aug 12 at 11:46


cfg


configparser.ConfigParser





Sorry, forgot to mention that. Yes they are
– Bluscream
Aug 12 at 11:54




1 Answer
1



First let me say I doubt the unnecessary I/O load matters and what you want to do is likely a case of premature optimization.



That said, here's an approach that seems to work — although I haven't tested it thoroughly or attempted to incorporated it into your loadCfg() and saveCfg() functions. (Whose names don't follow the PEP 8 - Style Guide for Python Code recommended naming convention for functions, BTW).


loadCfg()


saveCfg()



The basic idea is to convert the initial ConfigParser instance into an dictionary and save it. Then, before closing the application, do that again and compare the before and after dictionaries to determine whether they're the same or not.


ConfigParser


from configparser import ConfigParser
import os


def as_dict(config): # Utility function.
"""
Converts a ConfigParser object into a dictionary.

The resulting dictionary has sections as keys which point to a dict
of the sections options as key => value pairs.

From https://stackoverflow.com/a/23944270/355230
"""
the_dict =

for section in config.sections():
the_dict[section] =
for key, val in config.items(section):
the_dict[section][key] = val

return the_dict


def loadCfg(path, cfg):
"""
:param path:
:param cfg:
"""
if not os.path.isfile(path) or os.path.getsize(path) < 1:
saveCfg(path, cfg)
cfg.read(path, encoding='utf-8') # "read" doesn't return a value.


def saveCfg(path, cfg):
"""
:param path:
:param cfg:
"""
with open(path, mode='w', encoding="utf-8") as cfgfile:
cfg.write(cfgfile)


if __name__ == '__main__':

# Create a config file for testing purposes.
test_config = ConfigParser()
test_config.add_section('Section1')
test_config.set('Section1', 'an_int', '15')
test_config.set('Section1', 'a_bool', 'true')
test_config.set('Section1', 'a_float', '3.1415')
test_config.set('Section1', 'baz', 'fun')
test_config.set('Section1', 'bar', 'Python')
saveCfg('example.cfg', test_config)

# Read it back in.
config = ConfigParser()
loadCfg('example.cfg', config)

before_dict = as_dict(config) # Convert it to a dict and save.

# Change it (comment-out next line to eliminate difference).
config.set('Section1', 'an_int', '42')

after_dict = as_dict(config) # Convert possibly updated contents.

# Only update the config file if contents of configparser is now different.
if after_dict == before_dict:
print('configuration not changed, config file not rewritten')
else:
print('configuration has changed, updating config file')
saveCfg('example.cfg', config)





Well, that is a premium answer and works great. Thank you very much!
– Bluscream
Aug 12 at 20:13







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard