Parsing a file configuration with the same section name in python

I am trying to parse a file like:

[account] User = first [account] User = second 

I use ConfigParser in Python, but when I read the file:

 Config = configparser.ConfigParser() Config.read(file) print (Config.sections()) 

I have an error:

 While reading from ... : section 'account' already exists 

How can I parse this file? Any other library? (preferred for python3)

+8
python configparser
source share
4 answers

If you just want to merge the identical named sections (the last one winnings), just pass the strict=False parameter to the constructor (added in Python 3.2). You effectively get the behavior of dict.update() as duplicate sections merge.

 Config = configparser.ConfigParser(strict=False) 

However, it is clear from the OP sample data that identically named partitions must be stored separately to avoid data loss. ConfigParser stores sections that it reads in the dictionary, so it cannot process multiple sections with the same name. Fortunately, the constructor accepts the dict_type argument, which allows you to specify another dictionary-like object. You can use this to support equally named sections. Here's a tough decision that manages section names by adding a unique number whenever the section name has been noticed before.

 from collections import OrderedDict class multidict(OrderedDict): _unique = 0 # class variable def __setitem__(self, key, val): if isinstance(val, dict): self._unique += 1 key += str(self._unique) OrderedDict.__setitem__(self, key, val) Config = configparser.ConfigParser(defaults=None, dict_type=multidict, strict=False) 

With a little work, you should be able to create a cleaner solution.

+11
source share

On the last python there is an option that can do what you want: ConfigParser(strict=True)

Cf: https://docs.python.org/3/library/configparser.html#configparser.ConfigParser

+2
source share

Unfortunately, the format of the ini file provided is incorrect in accordance with the standards. The section name must be unique in the document.

If you can change the file format (I already read that you cannot, but for completeness ...), then a suitable solution would be suitable:

 [accounts] keys= account1, account2 [account1] User = first [account2] User = second 

If you really cannot interchange the file format, I fear that your only option is to manually parse the configuration file.

+1
source share

"If you deviate from the RFC standard and create your own configuration format, you will have to write your own parser." This http://www.tek-tips.com/viewthread.cfm?qid=1110829 worked for me. I made a couple of small changes. ** formatting did not work correctly when laid out

 def configToDict(file): # open the file file = open('settings.cfg') # create an empty dict sections = {} for line in file.readlines(): # get rid of the newline line = line[:-1] try: # this will break if you have whitespace on the "blank" lines if line: # skip comment lines if line[0] == '#': next # this assumes everything starts on the first column if line[0] == '[': # strip the brackets section = line[1:-1] # create a new section if it doesn't already exist if not sections.has_key(section): sections[section] = {} else: # split on first the equal sign (key, val) = line.split('=', 1) # create the attribute as a list if it doesn't # exist under the current section, this will # break if there no section set yet if not sections[section].has_key(key): sections[section][key] = [] # append the new value to the list sections[section][key].append(val) except Exception as e: print str(e) + "line:" +line return sections 
0
source share

All Articles