我有一个yaml设置文件,该文件在db中创建一些记录:
setting1:
name: [item,item]
name1: text
anothersetting2:
name: [item,item]
sub_setting:
name :[item,item]
当我用 setter3 和DB中的记录更新此文件时:
import yaml
fh = open('setting.txt', 'r')
setting_list = yaml.load(fh)
for i in setting_list:
add_to_db[i]
至关重要的是,它们的设置顺序(db中的ID号)每次都与im addig保持在db ...和设置3只是将其附加到yaml.load()的结尾很重要。ID不会混淆DB中已经存在的任何记录...目前,每次我添加另一个设置并调用yaml.load()记录以不同的顺序加载,从而导致不同的ID。我欢迎任何想法;)
编辑:我已经遵循了 abarnert 提示,并接受了此GIST https://gist.github.com/8444388
效果按预期的效果,谢谢!
我的项目oyaml
是PYYAML的置换式替代品,它将将映射加载到collections.OrderedDict
而不是常规dicts中。只需pip安装它并按照普通方式使用 - 在Python 3和Python 2上使用。
与您的示例演示:
>>> import oyaml as yaml # pip install oyaml
>>> yaml.load('''setting1:
... name: [item,item]
... name1: text
... anothersetting2:
... name: [item,item]
... sub_setting:
... name :[item,item]''')
OrderedDict([('setting1',
OrderedDict([('name', ['item', 'item']), ('name1', 'text')])),
('anothersetting2',
OrderedDict([('name', ['item', 'item']),
('sub_setting', 'name :[item,item]')]))])
请注意,如果stdlib dict是保留订单(python> = 3.7,cpython> = 3.6),则oyaml
将使用普通的dict。
您现在可以使用 ruaml.yaml 为此。
来自https://pypi.python.org/pypi/ruamel.yaml:
ruamel.yaml是支持往返的yaml解析器/发射器 保存评论,SEQ/MAP FLOW样式和地图密钥顺序
YAML规范清楚地表明,映射中的密钥顺序是无法依赖的"表示详细信息"。因此,如果您的设置文件依赖映射,则已经无效了,如果可能的话,您会更好地使用有效的YAML。
当然是可扩展的,没有什么可以阻止您在设置文件中添加"有序映射"类型。例如:
!omap setting1:
name: [item,item]
name1: text
!omap anothersetting2:
name: [item,item]
!omap sub_setting:
name :[item,item]
您没有提及您正在使用的yaml
模块。标准库中没有这样的模块,并且PYPI上至少有两个包装,它们为模块提供了该名称。但是,我猜是Pyyaml,因为据我所知,这是最受欢迎的。
上面描述的扩展很容易用pyyaml解析。请参阅http://pyyaml.org/ticket/29:
def omap_constructor(loader, node):
return loader.construct_pairs(node)
yaml.add_constructor(u'!omap', omap_constructor)
现在,而不是:
{'anothersetting2': {'name': ['item', 'item'],
'sub_setting': 'name :[item,item]'},
'setting1': {'name': ['item', 'item'], 'name1': 'text'}}
您会得到这个:
(('anothersetting2', (('name', ['item', 'item']),
('sub_setting', ('name, [item,item]'),))),
('setting1', (('name', ['item', 'item']), ('name1', 'text'))))
当然,这为您提供了键值tuple
s的tuple
,但是您可以轻松编写construct_ordereddict并获得OrderedDict
。您还可以编写一个代表,如果您需要输出和输入,将OrdereredDict
对象存储为!omap
s。
如果您真的想挂接pyyAml以使其使用OrderedDict
而不是dict
用于默认映射,则如果您已经直接在Parser对象上工作,则很容易做到,但是如果您坚持使用该映射高级便利方法。幸运的是,上述机票具有您可以使用的实现。只需记住,您不再使用真实的YAML,而是一个变体,因此处理您的文件的任何其他软件都可以并且可能会破坏。
对于给定的单个项目,该项目已知是有序的字典,只需制作列表的项目和使用的集合。
setting1:
- name: [item,item]
- name1: text
anothersetting2:
- name: [item,item]
- sub_setting:
name :[item,item]
import collections
import yaml
fh = open('setting.txt', 'r')
setting_list = yaml.load(fh)
setting1 = collections.OrderedDict(list(x.items())[0] for x in setting_list['setting1'])
上次我听到的,pyyaml不支持这一点,尽管它可能很容易修改它接受字典或字典式对象作为起点。
Div>