Tuesday 10 July 2012

Simple python config

Often when I'm writing python code I'll be setting some values and think to myself "Gee, these values should really be stored in a config file". That thought is often followed by "Nah, too much effort. This is just a quick script anyhow". If there was a way of making using config files almost zero effort then I'd be more likely to use them and not have to deal with my "quick script" now being a couple of hundred lines of code and having no easy way of changing the configuration.

Python's ConfigParser module can do most of the work, but there are still some things that make it just that little bit of effort to use.

  • It doesn't know/care about types. Everything is just a string. You have to consciously call getint or getfloat etc depending on what type you want.
  • I'd prefer to just have a simple dictionary with all my values in it - config['section:key'] looks neater than config.get('section', 'key') (to me anyhow)
  • It can't deal with config files that don't have a section in them
  • If I'm working on amazingProgram.py I'd like it to default to using amazingProgram.cfg without having to explicitly tell it.
I've written a fairly simple function to get around these issues. It uses ConfigParser to read the config file, and turns it into a simple dictionary. For each value it determines if it is a int, float, bool (denoted by any of 'true', 'yes', 'on', 'false', 'no', 'off') or if none of these leaves it as a string.

You can tell it which config file to read, but if none is given it will take the name of the file containing the __main__ function, and replace the '.py' with '.cfg'. Using it is as simple as
import simpleConfig

config = simpleConfig.parseConfig()
So let's say I have a config file called test.cfg which contains
host = localhost
port = 8080
delay = 1.0
use_tcp = true

And I make a test.py with
import simpleConfig

config = simpleConfig.parseConfig()

if config['use_tcp']:
        print config['host'], type(config['host'])
        print config['port'], type(config['port'])
        print config['delay'], type(config['delay'])
When I run it I get
[rlawther@wagner tmp]$ python test.py
localhost <type 'str'>
8080 <type 'int'>
1.0 <type 'float'>
So hopefully, next time I think I should put something in a config file I'll use this rather than not bothering.

1 comment: