0

I have 15 values that I want to get from a config file and store them in separate variables.

I am using

from ConfigParser import SafeConfigParser

parser = SafeConfigParser()
parser.read(configFile)

and it is a really good library.

Option #1

If I change the name of the variable and want it to match the config file entry I have to edit the corresponding line in the function

def fromConfig():
    #open file
    localOne = parser.get(section, 'one')
    localTwo = parser.get(section, 'two')
    return one, two

one = ''
two = ''
#etc
one, two = fromConfig()

Option #2

It is cleaner to see where the variables get their values from, but then I would be opening and closing the file for every variable

def getValueFromConfigFile(option):
    #open file
    value = parser.get(section, option)
    return value

one = getValueFromConfigFile("one")
two = getValueFromConfigFile("two")

Option #3

This one doesn't make much sense since I have to have another list of all my variable names, but the function is cleaner.

def getValuesFromConfigFile(options):
    #open file
    values = []
    for option in options:
        values.append(parser.get(section, option))

    return values

one = ''
two = ''
configList = ["one", "two"]
one, two = getValuesFromConfigFile(configList)

EDIT: Here is my attempt at reading the file one and storing all values in a dict and then trying to use he values. I have a multi-lined string and I am using

%(nl)s to be a new line character so then when I get the value 
message = parser.get(section, 'message', vars={'nl':'\n'})

Here is my code:

from ConfigParser import SafeConfigParser

def getValuesFromConfigFile(configFile):
    ''' reads a single section of a config file as a dict '''
    parser = SafeConfigParser()
    parser.read(configFile)
    section = parser.sections()[0]

    options = dict(parser.items(section))

    return options


options = getValuesFromConfigFile(configFile)

one = options["one"]
Siecje
  • 3,594
  • 10
  • 32
  • 50

3 Answers3

3

To get values from a single section as a dict:

options = dict(parser.items(section))

You could access individual values as usual: options["one"], options["two"]. In Python 3.2+ configparser provides dict-like access by itself.

For flexibility, to support updating config from a variety of source formats and/or centralize configuration management; you could define custom class that encapsulates parsing/access to config variables e.g.:

class Config(object):
    # ..    
    def update_from_ini(self, inifile):
        # read file..
        self.__dict__.update(parser.items(section))

Individual values are available as instance attributes in this case: config.one, config.two.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • 1
    You can also use [`configparser`](http://pypi.python.org/pypi/configparser/3.3.0r2) to get the 3.2+ module in 2.x. – abarnert Feb 04 '13 at 23:18
  • So I should read all of the values from the config file into a dict and then set each variable name = dict[name] and then I am only opening and read the config file once, ok I will try that – Siecje Feb 04 '13 at 23:28
  • @Siecje: There is no point to create a dict if you use it only to put each value into a separate variable. You could use: `get = functools.partial(parser.get, section)` and later call `get("one")` if you insist on separate variables. Though it is preferable to use a single dict/custom object to access the config instead of 15 separate variables for readability and maintainability. – jfs Feb 04 '13 at 23:44
  • I have updated my code to try and implement it but I am using a substitution so that I can have newline characters in my message. – Siecje Feb 05 '13 at 15:46
1

A solution could be as well to use dictionaries & json which can make things verry easy & reusable

import json

def saveJson(fName, data):
    f = open(fName, "w+")
    f.write(json.dumps(data, indent=4))
    f.close()

def loadJson(fName):
    f = open(fName, "r")
    data = json.loads(f.read())
    f.close()
    return data

mySettings = {
    "one": "bla",
    "two": "blabla"
}

saveJson("mySettings.json", mySettings)
myMoadedSettings = loadJson("mySettings.json")

print myMoadedSettings["two"]
kolergy
  • 2,313
  • 2
  • 13
  • 14
0

As a possible solution:

module_variables = globals() # represents the current global symbol table
for name in ('one', 'two'):
    module_variables[name] = parser.get(section, name)
print one, two
newtover
  • 31,286
  • 11
  • 84
  • 89
  • @siecje, http://docs.python.org/2/library/functions.html#locals – newtover Feb 04 '13 at 21:22
  • The docs states that the result of the locals() should not be modified, but the trick with the globals() does work as well, though this will be the module scope. – newtover Feb 04 '13 at 21:25