我正在使用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),这对于可读性来说也是不错的。
答案 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,因此我必须指定标记,但系统确实有效。