12

コンピューターには 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 など) は、読みやすさにも役立ちます。

4

1 に答える 1

18

これは、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 を指定できないため、タグを指定する必要がありますが、システムは機能します。

于 2012-12-22T09:36:38.397 に答える