我有一个yaml设置文件,它在db中创建一些记录:
setting1:
name: [item,item]
name1: text
anothersetting2:
name: [item,item]
sub_setting:
name :[item,item]
Run Code Online (Sandbox Code Playgroud)
当我使用setting3更新此文件并在db中重新生成记录时:
import yaml
fh = open('setting.txt', 'r')
setting_list = yaml.load(fh)
for i in setting_list:
add_to_db[i]
Run Code Online (Sandbox Code Playgroud)
至关重要的是,它们的设置顺序(db中的id号)每次都保持相同,因为我将它们添加到db ...并且setting3只是附加到yaml.load()的末尾,因此它的id不会'混淆已经在数据库中的任何记录......每次我添加另一个设置并调用yaml.load()记录时,会以不同的顺序加载,从而产生不同的ID.我欢迎任何想法;)
编辑: 我已经遵循了abarnert提示并采取了这个要点https://gist.github.com/844388
按预期工作谢谢!
wim*_*wim 11
oyaml是PyYAML的直接替代品,它将加载地图collections.OrderedDict而不是常规的dicts.只需点击安装并正常使用 - 适用于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]')]))])
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用ruaml.yaml。
来自https://pypi.python.org/pypi/ruamel.yaml:
ruamel.yaml是一个YAML解析器/发射器,它支持注释,seq /映射流样式和映射键顺序的往返保留。
YAML 规范明确指出映射中的键顺序是不可依赖的“表示细节”。因此,如果您的设置文件依赖于映射,则它已经无效,并且如果可能的话,最好使用有效的 YAML。
当然,YAML 是可扩展的,并且没有什么可以阻止您向设置文件添加“有序映射”类型。例如:
!omap setting1:
name: [item,item]
name1: text
!omap anothersetting2:
name: [item,item]
!omap sub_setting:
name :[item,item]
Run Code Online (Sandbox Code Playgroud)
您没有提到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)
Run Code Online (Sandbox Code Playgroud)
现在,代替:
{'anothersetting2': {'name': ['item', 'item'],
'sub_setting': 'name :[item,item]'},
'setting1': {'name': ['item', 'item'], 'name1': 'text'}}
Run Code Online (Sandbox Code Playgroud)
你会得到这个:
(('anothersetting2', (('name', ['item', 'item']),
('sub_setting', ('name, [item,item]'),))),
('setting1', (('name', ['item', 'item']), ('name1', 'text'))))
Run Code Online (Sandbox Code Playgroud)
当然,这为您提供了一个tuplekey-value tuple,但是您可以轻松地编写一个 Construction_ordereddict 并获得一个OrderedDict。如果您需要输出和输入,您还可以编写一个将OrdereredDict对象存储为 s 的表示器。!omap
如果您确实想挂钩 PyYAML 以使其使用 anOrderedDict而不是 adict作为默认映射,那么如果您已经直接处理解析器对象,那么这很容易做到,但如果您想坚持使用高级便捷方法,则更加困难。幸运的是,上面链接的票证有一个可以使用的实现。请记住,您不再使用真正的 YAML,而是使用变体,因此处理您的文件的任何其他软件都可能而且很可能会崩溃。