Python配置解析器(重复密钥支持)

时间:2011-03-22 18:35:52

标签: python configuration yaml config

所以我最近开始为我正在研究的Python项目编写一个配置解析器。我最初避免使用configparser和configobj,因为我想支持这样的配置文件:

key=value
key2=anothervalue

food=burger
food=hotdog
food=cake icecream

简而言之,这个配置文件将经常通过SSH命令行进行编辑。因此我不想对间距进行制表或挑剔(如YAML),但我也希望避免使用多个值(容易10个或更多)的行在vi中换行。这就是我想支持重复键的原因。

一个我的理想世界,当我向Python配置对象询问食物时,它会给我一个回复列表['burger','hotdog','cake','icecream']。如果没有定义食物值,它会查看默认配置文件并给我/那些值。

我已经实施了上述

然而,当我意识到我想支持保留内联评论等时,我的麻烦就开始了。我处理读取和写入配置文件的方式是将文件解码为内存中的dict,读取dict中的值,或将值写入dict,然后将该dict转储回文件。这对于保留行顺序和评论等并不是很好,而且它正在惹恼我。

A)ConfigObj看起来像我需要的一切,除了支持重复键。相反,它希望我制作一个列表,由于换行,在vi上通过ssh手动编辑会很麻烦。我可以使configobj更ssh / vi友好吗?

B)我的自制软件解决方案有问题吗?有没有更好的方法来读/写/存储我的配置值?有没有简单的方法来处理更改配置文件中的键值,只需修改该行并从内存中重写整个配置文件?

2 个答案:

答案 0 :(得分:0)

疯狂的想法:将您的字典值作为包含行号,列号和值本身的3元组列表,并添加特殊键以供评论。

CommentSymbol = ';'
def readConfig(filename):
    f = open(filename, 'r')
    if not f:
        return
    def addValue(dict, key, lineIdx, colIdx, value):
        if key in dict:
            dict[key].append((lineIdx, colIdx, value))
        else:
            dict[key] = [(lineIdx, colIdx, value)]
    res = {}
    i = 0
    for line in f.readlines():
        idx = line.find(CommentSymbol)
        if idx != -1:
            comment = line[idx + 1:]
            addValue(res, CommentSymbol, i, idx, comment)
            line = line[:idx]
        pair = [x.strip() for x in line.split('=')][:2]
        if len(pair) == 2:
            addValue(res, pair[0], i, 0, pair[1])
        i += 1
    return res

def writeConfig(dict, filename):
    f = open(filename, 'w')
    if not f:
        return
    index = sorted(dict.iteritems(), cmp = lambda x, y: cmp(x[1][:2], y[1][:2]))
    i = 0
    for k, V in index:
        for v in V:
            if v[0] > i:
                f.write('\n' * (v[0] - i - 1))
            if k == CommentSymbol:
                f.write('{0}{1}'.format(CommentSymbol, str(v[2])))
            else:
                f.write('{0} = {1}'.format(str(k), str(v[2])))
            i = v[0]
    f.close() 

答案 1 :(得分:0)

如果可以的话,我当然会尝试利用标准库中的内容。

配置解析器类的签名如下所示:

class ConfigParser.SafeConfigParser([defaults[, dict_type[, allow_no_value]]])

注意dict_type参数。提供时,这将用于构造节的列表,节的选项和默认值的字典对象。它默认为collections.OrderedDict。也许你可以在那里传递一些东西来获得你想要的多键行为,然后获得ConfigParser的所有优点。您可能必须编写自己的类才能执行此操作,或者您可能会在PyPi或ActiveState配方中找到一个为您编写的类。尝试寻找包或多重课程。

我要么走这条路,要么只是把它拿出来制作清单:

foo = value1, value2, value3