why use special config formats?

tomerfiliba at gmail.com tomerfiliba at gmail.com
Fri Mar 10 15:48:03 CET 2006


hey

i've been seeing lots of config-file-readers for python. be it
ConfigObj (http://www.voidspace.org.uk/python/configobj.html) or the
like. seems like a trend to me.
i came to this conclusion a long time ago: YOU DON'T NEED CONFIG FILES
FOR PYTHON. why re-invent stuff and parse text by yourself, why the
interpreter can do it for you? and anyway, i find this a very ugly
format:
http://www.voidspace.org.uk/python/configobj.html#the-config-file-format

there are two use cases for configuration: static vs. dynamic
configuration.

for the most common case, static configuration, you just have a
human-edited config file holding key-and-value pairs. so just add to
your package a file called config.py, and import it.

for example, if that's our package structure:
PyApache/
    __init__.py
    config.py
    server.py

then server.py would do:
...
import config
listener_sock.bind((config.host, config.port))
...

and config.py would look like:
# the port to bind to
port = 80
host = "localhost"
timeout  = 300
enable_keep_alives = False
options = [1, 2, 3]
...

isn't python suitable enough to hold your configuration?

the second case, dynamic configuration, is when you need to alter your
configuration at runtime or programatically, so the configuration
doesnt need to be human-readable. for that case -- use pickle. and
Bunch (as shown on the aspn python cookbook)

class Bunch(object):
    def __init__(self, **kw):
         self.__dict__.update(kw)

create the initial config file:
config = Bunch(port = 80, host = "localhost", timeout = 300, ...)
pickle.dump(open("config.pkl", "wb"), config)

of course you can nest Bunch'es inside one another, i.e.,
config = Bunch(
    # global config
    port = 80,
    host = "localhost",

    # this is per-user configuration
    users = {
        "malcom_x" : Bunch(
            http_path = "/home/joe/httpdocs",
            cgi_path = "/home/joe/cgi-bin",
            options = ["i love lucy", "bush is gay"]
        ),
        ...
     },
     ...
)

and now you use it:
# global configuration
config = pickle.load(open("config.pkl"))
listener_sock.bind((config.host, config.port))
# and per-user configuration
from getpass import getuser
print config.users[getuser()].http_path
...

that way, if you need to programatically change your configuration,
just change and pickle.dump() it. 

hope it helps,
-tomer




More information about the Python-list mailing list