问题
I try to parse file like:
[account]
User = first
[account]
User = second
I use ConfigParser in Python, but when i read file:
Config = configparser.ConfigParser()
Config.read(file)
print (Config.sections())
I have error:
While reading from ... : section 'account' already exists
How can i parse this file? Are any another library? (prefer for python3)
回答1:
If what you want is to simply merge identically named sections (latest one wins), simply pass the strict=False
option to the constructor (added in Python 3.2).
You effectively get dict.update()
behavior as the duplicate sections are merged in.
Config = configparser.ConfigParser(strict=False)
However, it's clear from the OP's sample data that identically named sections need to be kept separate, to avoid loss of data. ConfigParser
stores the sections it reads in a dictionary, so it can't handle multiple sections with the same name. Fortunately the constructor accepts a dict_type
argument that allows you to specify a different dictionary-like object. You can use that to support identically named sections. Here's a crude solution that mangles the section names by appending a unique number whenever a section name has been seen 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 construct a cleaner solution.
回答2:
On the latest python there is an option that may do what you want :
ConfigParser(strict=True)
Cf : https://docs.python.org/3/library/configparser.html#configparser.ConfigParser
回答3:
Unfortunately, the format of the provided ini file is not correct according standards. A section's 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 solution like this would be appropriate:
[accounts]
keys= account1, account2
[account1]
User = first
[account2]
User = second
If you really can't alternate the file's format, then I fear that your only option is to parse manually the configuration file.
回答4:
" If you're deviating from an RFC standard and creating your own config format, you're going to 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 come out correctly when posted
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's 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
来源:https://stackoverflow.com/questions/9876059/parsing-configure-file-with-same-section-name-in-python