我尝试解析文件:
[account]
User = first
[account]
User = second
我在Python中使用ConfigParser,但是当我读取文件时:
Config = configparser.ConfigParser()
Config.read(file)
print (Config.sections())
我有错误:
While reading from ... : section 'account' already exists
我该如何解析这个文件?还有其他图书馆吗? (更喜欢python3)
答案 0 :(得分:15)
如果你想要的只是简单地合并相同名称的部分(最新的一个获胜),只需将strict=False
选项传递给构造函数(在Python 3.2中添加)。
在合并重复部分时,您可以有效地获得dict.update()
行为。
Config = configparser.ConfigParser(strict=False)
然而,从OP的样本数据可以清楚地看出,相同名称的部分需要保持分离,以避免数据丢失。 ConfigParser
将它读取的部分存储在字典中,因此它无法处理具有相同名称的多个部分。幸运的是,构造函数接受dict_type
参数,允许您指定不同的类字典对象。您可以使用它来支持具有相同名称的部分。这是一个粗略的解决方案,通过在之前看到部分名称时附加一个唯一的数字来破坏部分名称。
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)
通过一些工作,你应该能够构建一个更清洁的解决方案。
答案 1 :(得分:2)
在最新的python上有一个选项可以做你想要的:
ConfigParser(strict=True)
Cf:https://docs.python.org/3/library/configparser.html#configparser.ConfigParser
答案 2 :(得分:1)
不幸的是,根据标准,提供的ini文件的格式不正确。部分的名称在文档中必须是唯一的。
如果您可以更改文件格式(我已经读过您不能,但为了完整性......),那么这样的解决方案是合适的:
[accounts]
keys= account1, account2
[account1]
User = first
[account2]
User = second
如果你真的无法替换文件的格式,那么我担心你唯一的选择是手动解析配置文件。
答案 3 :(得分:0)
” 如果您偏离RFC标准并创建自己的配置格式,那么您将不得不编写自己的解析器。“这http://www.tek-tips.com/viewthread.cfm?qid=1110829对我有用。我做了一些小改动。**格式化发布后发布不正确
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