首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用带有重复选项的ConfigParser编写INI文件

如何使用带有重复选项的ConfigParser编写INI文件
EN

Stack Overflow用户
提问于 2015-06-03 08:42:09
回答 2查看 2.3K关注 0票数 2

我想编写一个包含重复选项的INI文件,即:

代码语言:javascript
运行
复制
[test]
foo = value1
foo = value2
xxx = yyy

使用ConfigParser.set,只编写最后一个值。

代码语言:javascript
运行
复制
config = ConfigParser.ConfigParser()
config.read('example.cfg')

config.add_section('test')
config.set('test', service['foo'], service['value1'])
config.set('test', service['foo'], service['value2'])
config.set('test', service['xxx'], service['yyy'])

结果是:

代码语言:javascript
运行
复制
[test]
foo = value2
xxx = yyy

有办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-04 06:54:22

看起来这是不可能的简单的方式。ConfigParser存储的默认方式是dict的,即每个唯一键一个值。

在一个类似的问题中,Python的ConfigParser唯一键的建议如下:

票数 0
EN

Stack Overflow用户

发布于 2015-06-03 08:55:10

我有一个python解析器 (为另一个项目构建),它使用一个列表来存储值,但前提是它们不是key=value格式的。如果是key=value,那么最后一次key将被保存,因为它们都存储在字典中

解析器还可以解析嵌套部分,如:

代码语言:javascript
运行
复制
[SECTION1][SECTION2]
key1=value1
; etc..

下面的代码很容易修改,可以将键/值存储在列表中而不是字典中,甚至可以检测到多个键并重新命名以避免冲突(例如keykey$1第二个键和相同键值的key等等)。视需要使用/修改

代码语言:javascript
运行
复制
##
#
#   Simple .ini Parser for Python 2.x, 3.x
#
##
import re

class Ini_Parser():
    """Simple .ini parser for Python"""

    NL = None

    ACTUAL = {
        '\\n' : "\n",
        '\\t' : "\t",
        '\\v' : "\v",
        '\\f' : "\f"
    }

    def parseStr(s, q):
        _self = Ini_Parser

        endq = s.find(q, 1)
        quoted = s[1:endq]
        rem = s[endq+1:].strip()
        for c,actual in _self.ACTUAL.items():
            quoted = ( actual ).join( quoted.split( c ) )
        quoted = ( '\\' ).join( quoted.split( '\\\\' ) )
        return quoted, rem

    def fromString(s, keysList=True, rootSection='_'):
        _self = Ini_Parser

        comments = [';', '#']

        if rootSection:  rootSection = str(rootSection)
        else: rootSection = '_'

        if not _self.NL:
            _self.NL = re.compile(r'\n\r|\r\n|\r|\n')

        sections = {}
        currentSection = str(rootSection)
        if keysList:
            sections[currentSection] = { '__list__' : [] }
        else:
            sections[currentSection] = {  }
        currentRoot = sections

        # parse the lines
        lines = re.split(_self.NL, str(s))

        # parse it line-by-line
        for line in lines:
            # strip the line of extra spaces
            line = line.strip()
            lenline = len(line)

            # comment or empty line, skip it
            if not lenline or (line[0] in comments): continue

            linestartswith = line[0]

            # section line
            if '['==linestartswith:

                SECTION = True

                # parse any sub-sections
                while '['==linestartswith:

                    if SECTION:
                        currentRoot = sections
                    else:
                        currentRoot = currentRoot[currentSection]

                    SECTION = False

                    endsection = line.find(']', 1)
                    currentSection = line[1:endsection]

                    if currentSection not in currentRoot:

                        if keysList:
                            currentRoot[currentSection] = { '__list__' : [] }
                        else:
                            currentRoot[currentSection] = {  }


                    # has sub-section ??
                    line = line[endsection+1:].strip()

                    if not len(line):  break

                    linestartswith = line[0]

            # key-value pairs
            else:

                # quoted string
                if '"'==linestartswith or "'"==linestartswith:

                    key, line = _self.parseStr(line, linestartswith)

                    # key-value pair
                    if line.find('=', 0)>-1:
                        line = line.split('=')
                        line.pop(0)
                        value = "=".join(line).strip()
                        valuestartswith = value[0]

                        # quoted value
                        if '"'==valuestartswith or "'"==valuestartswith:
                            value, rem = _self.parseStr(value, valuestartswith)

                        currentRoot[currentSection][key] = value

                    # single value
                    else:

                        if keysList:
                            currentRoot[currentSection]['__list__'].append(key)
                        else:
                            currentRoot[currentSection][key] = True


                # un-quoted string
                else:

                    line = line.split('=')
                    key = line.pop(0).strip()

                    # single value
                    if 1>len(line):

                        if keysList:
                            currentRoot[currentSection]['__list__'].append(key)
                        else:
                            currentRoot[currentSection][key] = True

                    # key-value pair
                    else:

                        value = "=".join(line).strip()
                        valuestartswith = value[0]

                        # quoted value
                        if '"'==valuestartswith or "'"==valuestartswith:
                            value, rem = _self.parseStr(value, valuestartswith)

                        currentRoot[currentSection][key] = value


        return sections


    def fromFile(filename, keysList=True, rootSection='_'):
        s = ''
        with open(filename, 'r') as f:  s = f.read()
        return Ini_Parser.fromString(s, keysList, rootSection)


    def walk(o, key=None, top='', q='', EOL="\n"):
        s = ''

        if len(o):

            o = dict(o)

            if key: keys = [key]
            else: keys = o.keys()

            for section in keys:

                keyvals = o[section]
                if not len(keyvals):  continue

                s += str(top) + "[" + str(section) + "]" + EOL

                if ('__list__' in keyvals) and len(keyvals['__list__']):

                    # only values as a list
                    s += q + (q+EOL+q).join(keyvals['__list__']) + q + EOL
                    del keyvals['__list__']


                if len(keyvals):

                    for k,v in keyvals.items():

                        if not len(v): continue

                        if isinstance(v, dict) or isinstance(v, list):

                            # sub-section
                            s += Ini_Parser.walk(keyvals, k, top + "[" + str(section) + "]", q, EOL)

                        else:

                            # key-value pair
                            s += q+k+q+ '=' +q+v+q + EOL



                s += EOL

        return s

    def toString(o, rootSection='_', quote=False, EOL="\n"):
        s = ''

        if rootSection: root = str(rootSection)
        else: root = '_'

        if quote: q = '"'
        else: q = ''

        # dump the root section first, if exists
        if root in o:
            section = dict(o[root])

            llist = None
            if '__list__' in section:
                llist = section['__list__']

                if llist and isinstance(llist, list) and len(llist):

                    s += q + (q+EOL+q).join(llist) + q + EOL
                    del section['__list__']


            for k,v in section.items():

                if not len(v): continue
                s += q+k+q+ '=' +q+v+q + EOL


            s += EOL

            del o[root]


        # walk the sections and sub-sections, if any
        s += Ini_Parser.walk(o, None, '', q, EOL)

        return s

    def toFile(filename, o, rootSection='_', quote=False, EOL="\n"):
        with open(filename, 'w') as f:  
            f.write( Ini_Parser.toString(o, rootSection, quote, EOL) )



# for use with 'import *'
__all__ = [ 'Ini_Parser' ]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30614996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档