Python 配置解析器(重复密钥支持) [英] Python Config Parser (Duplicate Key Support)
问题描述
所以我最近开始为我正在处理的 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 进行编辑.因此,我不想对间距进行制表符或挑剔(如 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 配置对象询问食物时,它会给我一个包含 ['burger', 'hotdog', 'cake', 'icecream'] 的列表.如果没有定义食物值,它会查看默认配置文件并给我那个/那些值.
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 看起来像我需要的一切,除了支持重复键.相反,它希望我制作一个列表,由于换行,在 vi 中通过 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) 我的自制解决方案错了吗?有没有更好的方式来读取/写入/存储我的配置值?是否有任何简单的方法可以通过修改该行并从内存中重写整个配置文件来处理更改配置文件中的键值?
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('
' * (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屋!