Python: How would you save a simple settings/config file?
Configuration files in python
There are several ways to do this depending on the file format required.
ConfigParser [.ini format]
I would use the standard configparser approach unless there were compelling reasons to use a different format.
Write a file like so:
# python 2.x# from ConfigParser import SafeConfigParser# config = SafeConfigParser()# python 3.xfrom configparser import ConfigParserconfig = ConfigParser()config.read('config.ini')config.add_section('main')config.set('main', 'key1', 'value1')config.set('main', 'key2', 'value2')config.set('main', 'key3', 'value3')with open('config.ini', 'w') as f: config.write(f)
The file format is very simple with sections marked out in square brackets:
[main]key1 = value1key2 = value2key3 = value3
Values can be extracted from the file like so:
# python 2.x# from ConfigParser import SafeConfigParser# config = SafeConfigParser()# python 3.xfrom configparser import ConfigParserconfig = ConfigParser()config.read('config.ini')print(config.get('main', 'key1')) # -> "value1"print(config.get('main', 'key2')) # -> "value2"print(config.get('main', 'key3')) # -> "value3"# getfloat() raises an exception if the value is not a floata_float = config.getfloat('main', 'a_float')# getint() and getboolean() also do this for their respective typesan_int = config.getint('main', 'an_int')
JSON [.json format]
JSON data can be very complex and has the advantage of being highly portable.
Write data to a file:
import jsonconfig = {"key1": "value1", "key2": "value2"}with open('config1.json', 'w') as f: json.dump(config, f)
Read data from a file:
import jsonwith open('config.json', 'r') as f: config = json.load(f)#edit the dataconfig['key3'] = 'value3'#write it back to the filewith open('config.json', 'w') as f: json.dump(config, f)
YAML
A basic YAML example is provided in this answer. More details can be found on the pyYAML website.
ConfigParser Basic example
The file can be loaded and used like this:
#!/usr/bin/env pythonimport ConfigParserimport io# Load the configuration filewith open("config.yml") as f: sample_config = f.read()config = ConfigParser.RawConfigParser(allow_no_value=True)config.readfp(io.BytesIO(sample_config))# List all contentsprint("List all contents")for section in config.sections(): print("Section: %s" % section) for options in config.options(section): print("x %s:::%s:::%s" % (options, config.get(section, options), str(type(options))))# Print some contentsprint("\nPrint some contents")print(config.get('other', 'use_anonymous')) # Just get the valueprint(config.getboolean('other', 'use_anonymous')) # You know the datatype?
which outputs
List all contentsSection: mysqlx host:::localhost:::<type 'str'>x user:::root:::<type 'str'>x passwd:::my secret password:::<type 'str'>x db:::write-math:::<type 'str'>Section: otherx preprocessing_queue:::["preprocessing.scale_and_center","preprocessing.dot_reduction","preprocessing.connect_lines"]:::<type 'str'>x use_anonymous:::yes:::<type 'str'>Print some contentsyesTrue
As you can see, you can use a standard data format that is easy to read and write. Methods like getboolean and getint allow you to get the datatype instead of a simple string.
Writing configuration
import osconfigfile_name = "config.yaml"# Check if there is already a configurtion fileif not os.path.isfile(configfile_name): # Create the configuration file as it doesn't exist yet cfgfile = open(configfile_name, 'w') # Add content to the file Config = ConfigParser.ConfigParser() Config.add_section('mysql') Config.set('mysql', 'host', 'localhost') Config.set('mysql', 'user', 'root') Config.set('mysql', 'passwd', 'my secret password') Config.set('mysql', 'db', 'write-math') Config.add_section('other') Config.set('other', 'preprocessing_queue', ['preprocessing.scale_and_center', 'preprocessing.dot_reduction', 'preprocessing.connect_lines']) Config.set('other', 'use_anonymous', True) Config.write(cfgfile) cfgfile.close()
results in
[mysql]host = localhostuser = rootpasswd = my secret passworddb = write-math[other]preprocessing_queue = ['preprocessing.scale_and_center', 'preprocessing.dot_reduction', 'preprocessing.connect_lines']use_anonymous = True
XML Basic example
Seems not to be used at all for configuration files by the Python community. However, parsing / writing XML is easy and there are plenty of possibilities to do so with Python. One is BeautifulSoup:
from BeautifulSoup import BeautifulSoupwith open("config.xml") as f: content = f.read()y = BeautifulSoup(content)print(y.mysql.host.contents[0])for tag in y.other.preprocessing_queue: print(tag)
where the config.xml might look like this
<config> <mysql> <host>localhost</host> <user>root</user> <passwd>my secret password</passwd> <db>write-math</db> </mysql> <other> <preprocessing_queue> <li>preprocessing.scale_and_center</li> <li>preprocessing.dot_reduction</li> <li>preprocessing.connect_lines</li> </preprocessing_queue> <use_anonymous value="true" /> </other></config>