Only save config if changed
Clash 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)
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.
I presume the
cfg
objects areconfigparser.ConfigParser
objects from the standard library?– Martin Ueding
Aug 12 at 11:46