Today I had an interesting problem with a python module I’m writing, and was provided with a nifty solution by a colleague which I thought I’d share.

The module relies on ConfigParser, which reads a configuration file, and returns an object which has methods such as get(), getboolean() etc. My module has a default configuration file path, and a method parse_config() which instantiates a (global) ConfigParser object as config. I wanted to allow the author importing my module to override the default config file, but not to have to explicitly opt whether or not to do so. The solution is as follows:

class LazyConfig(object):

    def __getattr__(self, s):
        parse_config()
        return getattr(config, s)

    config = LazyConfig()

When the module is imported, the LazyConfig class is instantiated as config. If the importer of the module does nothing, the first time config.get() is called, the getattr method of the class will run, and in turn call parse_config(), which will read the default file, create a config() object (overwriting the class), then call that object (via getattr). If the importer wishes to use a different configuration file, he simply has to call parse_config(“/foo/bar/baz.cfg”). Job done!


Matthew Richardson