4

I would like to read a configuration file in Python completely into a data structure without explicitly 'getting' each value. The reason for doing so is that I intend to modify these values programatically (for instance, I'll have a variable that says I want to modify [Foo] Bar = 1 to be [Foo] Bar = 2), with the intention of writing a new configuration file based on my changes.

At present, I'm reading all the values by hand:

parser = SafeConfigParser()
parser.read(cfgFile)
foo_bar1 = int(parser.get('Foo', 'Bar1'))
foo_bar2 = int(parser.get('Foo', 'Bar2'))

What I would love to have (didn't find much Google-wise) is a method to read them into a list, have them be identified easily so that I can pull that value out of the list and change it.

Essentially referencing it as (or similarly to):

config_values = parser.read(cfgFile)
foo_bar1      = config_values('Foo.bar1')
2
  • Could you just overload __getitem__ (or __call__) on a class that wraps the config parser? Then, when you do class['Foo.Bar1] (or class('Foo.Bar1')) you can split on the period and look it up in the config_parser object? It seems that what you want to do is very close to what the parser already does. Commented Nov 9, 2012 at 14:36
  • 1
    @SamMussmann -- It looks like we were thinking the same thing. Commented Nov 9, 2012 at 14:36

3 Answers 3

3

Sorry if I'm misunderstanding -- This really doesn't seem much different than what you have -- It seems like a very simple subclass would work:

class MyParser(SafeConfigParser):
    def __call__(self,path,type=int):
        return type(self.get(*path.split('.')))

and of course, you wouldn't actually need a subclass either. You could just put the stuff in __call__ into a separate function ...

Sign up to request clarification or add additional context in comments.

1 Comment

This looks interesting, but I'm slightly confused. Is this overloading the parser.read function? I'd like to just read all the config values into a list and then pull them out dictionary style (similar to @Ryan G's answer in a way)
2
import sys
from ConfigParser import SafeConfigParser

parser = SafeConfigParser()
parser.readfp(sys.stdin)

config = dict((section, dict((option, parser.get(section, option))
                             for option in parser.options(section)))
              for section in parser.sections())
print config

Input

[a]
b = 1
c = 2
[d]
e = 3

Output

{'a': {'c': '2', 'b': '1'}, 'd': {'e': '3'}}

Comments

2

Are you running python 2.7?

There's a nifty way, I discovered a few months back, to parse the config file and setup a dictionary using dictionary comprehension.

config = ConfigParser.ConfigParser()
config.read('config.cfg')
# Create a dictionary of complete config file, {'section':{'option':'values'}, ...}
configDict = {section:{option:config.get(section,option) for option in config.options(section)} for section in config.sections()}

Although this way is harder to read, it take's up less space, and you don't have to explicitly state every variable that you want to get.

  • Note: This won't work on python 2.6 (*that I know of). I've written scripts in the past where I used this, and since I'm running 2.7 on Windows, somebody on a linux machine, running 2.6, will crash on the dictionary comprehension.

--Edit--

You will need to still manually change the data types of the values.

6 Comments

That would be lovely...but yea I'm running 2.6 (had 2.7 tag on by mistake)
@espais: you could use it on Python 2.6 if you replace {k: v for ..} with dict((k, v) for ..)
@J.F.Sebastian: Am I missing something? cfg_dict = dict(section: dict(option:cfg.get(section,option) for option in cfg.options(section)) for section in cfg.sections()) throws an error on the 2nd param after cfg.options(section))
@espais: yes. Replace a: b with (a, b)
@J.F.Sebastian: sorry for my lack of Python-knowledge....but now I see this: SyntaxError: Generator expression must be parenthesized if not sole argument...I tried parenthesizing the 2nd argument but that didn't help
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.