Python配置解析器(重复键支持) [英] Python Config Parser (Duplicate Key Support)

查看:341
本文介绍了Python配置解析器(重复键支持)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I recently started writing a config parser for a Python project I'm working on. I initially avoided configparser and configobj, because I wanted to support a config file like so:

key=value
key2=anothervalue

food=burger
food=hotdog
food=cake icecream

总之,这个配置文件将经由SSH通过命令行进行编辑。所以我不想分页或finicky关于间距(像YAML),但我也想要避免键有多个值(容易10或更多)被包装在vi。这就是为什么我想支持重复键。

In short, this config file is going to be edited via the command line over SSH often. So I don't want to tab or finicky about spacing (like YAML), but I also want avoid keys with multiple values (easily 10 or more) being line wrapped in vi. This is why I would like to support duplicate keys.

一个我的理想世界,当我要求Python配置对象的食物,它会给我一个列表回来['汉堡','热狗' , '冰淇淋']。如果没有定义食物值,它将在默认配置文件中查找/给出那些值。

An my ideal world, when I ask the Python config object for food, it would give me a list back with ['burger', 'hotdog', 'cake', 'icecream']. If there wasn't a food value defined, it would look in a defaults config file and give me that/those values.

我已经实现了上述

然而,当我意识到我想支持保留内联注释等时,我的麻烦开始了。我处理读取和写入配置文件的方式是将文件解码为内存中的dict,从dict中读取值,或者向dict写入值,然后将该dict转储回文件。这不是真的很好,为了保持行顺序和评论,这样,它是错误的废话我。

However, my troubles started when I realized I wanted to support preserving inline comments and such. The way I handle reading and writing to the config files, is decoding the file into a dict in memory, read the values from the dict, or write values to the dict, and then dump that dict back out into a file. This isn't really nice for preserving line order and commenting and such and it's bugging the crap out of me.

A)ConfigObj看起来像我需要的一切,除了支持重复键。相反,它希望我做一个列表是一个痛苦,通过ssh手动编辑,由于换行。我可以让configobj更多的ssh / vi友好吗?

A) ConfigObj looks like it has everything I need except support duplicate keys. Instead it wants me to make a list is going to be a pain to edit manually in vi over ssh due to line wrapping. Can I make configobj more ssh/vi friendly?

B)我的homebrew解决方案是否错误?有没有更好的方式读/写/存储我的配置值?是否有任何简单的方法来处理更改配置文件中的键值只需修改该行并从内存重写整个配置文件?

B) Is my homebrew solution wrong? Is there a better way of reading/writing/storing my config values? Is there any easy way to handle changing a key value in a config file by just modifying that line and rewriting the entire config file from memory?

推荐答案

疯狂的想法:将您的字典值作为具有行号,列号和值本身的3元组列表,并添加特殊键以进行注释。

Crazy idea: make your dictionary values as a list of 3-tuples with line number, col number and value itself and add special key for comment.

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() 

这篇关于Python配置解析器(重复键支持)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆