为PyYAML转储的某些部分指定样式

时间:2012-12-22 07:19:43

标签: yaml pyyaml

我正在使用YAML作为计算机和人类可编辑和可读的模拟器输入格式。为了人类的可读性,输入的某些部分主要适用于阻止样式,而流程样式更适合其他部分。

PyYAML的默认设置是在嵌套地图或序列的任何地方使用块样式,在其他任何地方使用流样式。 * default_flow_style *允许选择all-flow-style或all-block-style。

但我想输出更多格式的文件

bonds:
- { strength: 2.0 }
- ...
tiles:
- { color: red, edges: [1, 0, 0, 1], stoic: 0.1}
- ...
args: 
    block: 2
    Gse: 9.4

可以看出,这并不是始终遵循一致的样式模式,而是根据文件的部分而改变。本质上,我希望能够指定某些块样式序列中的所有值都是流式样。有没有办法对转储进行那种精细级别的控制?能够以特定顺序转储顶级映射而不需要该顺序(例如,omap),这对于可读性来说也是不错的。

1 个答案:

答案 0 :(得分:13)

事实证明,这可以通过为每个我想要不遵循default_flow_style的项目定义具有表示符的子类来完成,然后在转储之前将所有必要的内容转换为那些。在这种情况下,这意味着我会得到类似的东西:

class blockseq( dict ): pass
def blockseq_rep(dumper, data):
    return dumper.represent_mapping( u'tag:yaml.org,2002:map', data, flow_style=False )

class flowmap( dict ): pass
def flowmap_rep(dumper, data):
    return dumper.represent_mapping( u'tag:yaml.org,2002:map', data, flow_style=True )

yaml.add_representer(blockseq, blockseq_rep)
yaml.add_representer(flowmap, flowmap_rep)

def dump( st ):
    st['tiles'] = [ flowmap(x) for x in st['tiles'] ]
    st['bonds'] = [ flowmap(x) for x in st['bonds'] ]
    if 'xgrowargs' in st.keys(): st['xgrowargs'] = blockseq(st['xgrowargs'])
    return yaml.dump(st)

令人讨厌的是,易于使用的dumper.represent_list和dumper.represent_dict不允许指定flow_style,因此我必须指定标记,但系统确实有效。