Welcome, guest | Sign In | My Account | Store | Cart

Many people use Python modules as config files, but this way your program may be manipulated or an syntax error may come into that file. Try the small script here to use the good old INI config files, known from Windows.

Python, 27 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import ConfigParser
import string

_ConfigDefault = {
    "database.dbms":            "mysql",
    "database.name":            "",
    "database.user":            "root",
    "database.password":        "",
    "database.host":            "127.0.0.1"
    }

def LoadConfig(file, config={}):
    """
    returns a dictionary with key's of the form
    <section>.<option> and the values 
    """
    config = config.copy()
    cp = ConfigParser.ConfigParser()
    cp.read(file)
    for sec in cp.sections():
        name = string.lower(sec)
        for opt in cp.options(sec):
            config[name + "." + string.lower(opt)] = string.strip(cp.get(sec, opt))
    return config

if __name__=="__main__":
    print LoadConfig("some.ini", _ConfigDefault)

This solution is just for reading config files. A write should be easy to be implemented. An INI file looks like this: <pre> [database] user = dummy password = tosca123 </pre> The defaults may be set in advance. The keys of the dictionary are always lower case, that helps ;-)

4 comments

Dave Primmer 22 years ago  # | flag

the writer... At first I saw this and said, "why concatenate the section and option?" seems like extra string processing right? it makes the write function harder i think. but once you get your dictionary, the values are easy to reference in your code.

here's the write function. i'm a newbie so it's probably not very tight code.

def write(self, file, config):
    """
    given a dictionary with key's of the form 'section.option: value'
    write() generates a list of unique section names
    creates sections based that list
    use config.set to add entries to each section
        """
    f= open(file,'w')
    cp = ConfigParser.ConfigParser()
    #a little string hacking because our section names are un-normalized
    #this builds a list of all the sections names
    sectionslst = []
    sections = []
    for k in config.keys():
        sectionslst.append(string.split(k,".")[0])
    #get unique entries
    sections = uniquer(sectionslst)
    for sec in sections:
        #make the headers
        cp.add_section(sec)
        #for each item in my dictionary
        #it splits the key in two and uses that for the first and second "set" args
        #then it uses the item.value for the 3rd arg
        # from 'section.option:value'
    for k in config.items():
        cp.set(string.split(k[0],".")[0],string.split(k[0],".")[1] ,k[1] )
    cp.write(f)
    f.close()

def uniquer(seq, idfun=None):
    if idfun is None:
        def idfun(x): return x
    seen = {}
    result = []
    for item in seq:
        marker = idfun(item)
        if marker in seen: continue
        seen[marker] = 1
        result.append(item)
    return result
James Stroud 17 years, 2 months ago  # | flag

An updated a tighter write(). This updates the write() function for python > 2.4 and makes it tighter and a little easier to understand.

Also, sets eliminate the need for uniquer().

def write(self, filename, config):
    """
    given a dictionary with key's of the form 'section.option: value'
    write() generates a list of unique section names
    creates sections based that list
    use config.set to add entries to each section
    """
    cp = ConfigParser.ConfigParser()
    sections = set([k.split('.')[0] for k in config.keys()])
    map(cp.add_section, sections)
    for k,v in config.items():
        s, o = k.split('.')
        cp.set(s, o, v)
    cp.write(open(filename, "w"))
Neal McBurnett 12 years, 11 months ago  # | flag

The "." character is allowed in section names, at least in the python implementation. So by concatenating the section and name strings together, separated by a ".", this code will give results that can't be unambiguously interpreted if the section name itself contains a "." (and perhaps if the name field does, depending on how it is used by the code that calls it).

Kirankumar N 12 years, 3 months ago  # | flag

I've a ini file in a remote linux machine say /usr123/bin/123.ini and the format inside the file be as below, [DB] datbasename:123 username:123 password:123 [abcd] ip:1.1.1.1 port:5050 by default, i need to login to the remote user usr123 and should replace the dflt values inside the file to [DB] databasename:456 username:456 password:456 [abcd] ip:2.2.2.2 port:5080 let me know how can a pass the parameters in the above code

Thanks in advance,