2016-05-10 11 views
1

に改行やインデントを追加safe_dump:解析した後PyYAMLと、YAMLファイル

--- 
classes: 
    - apache 
    - ntp 

apache::first: 1 
apache::package_ensure: present 
apache::port: 999 
apache::second: 2 
apache::service_ensure: running 

ntp::bla: bla 
ntp::package_ensure: present 
ntp::servers: '-' 

は、私がこのような出力を受信:

--- 
apache::first: 1 
apache::package_ensure: present 
apache::port: 999 
apache::second: 2 
apache::service_ensure: running 
classes: 
- apache 
- ntp 
ntp::bla: bla 
ntp::package_ensure: present 
ntp::servers: '-' 

Here、私が発見しましたドキュメントをスタイルする可能性を与えるプロパティ。私はline_breakとインデントを設定しようとしましたが、動作しません。

with open(config['REPOSITORY_PATH'] + '/' + file_name, 'w+') as file: 
      yaml.safe_dump(data_map, file, indent=10, explicit_start=True, explicit_end=True, default_flow_style=False, 
          line_break=1) 
     file.close() 

出力をスタイルする簡単な方法を教えてください。

+0

明示的に 'file.close()'を呼び出すべきではありません。with文を終了すると例外が発生してもファイルが閉じられます。 – Anthon

答えて

1

PyYAMLではこれを実行できません。 indentオプションはマッピングにのみ影響し、シーケンスには影響しません。 PyYAMLはラウンドトリップ時のマッピングキーの順序も保持しません。

あなたは(dislaimer:私はそのパッケージの作者午前)ruamel.yamlを使用する場合は、出力とまったく同じ入力を得ることは簡単です:

import ruamel.yaml 

yaml_str = """\ 
--- 
classes: 
    - apache # keep the indentation 
    - ntp 

apache::first: 1 
apache::package_ensure: present 
apache::port: 999 
apache::second: 2 
apache::service_ensure: running 

ntp::bla: bla 
ntp::package_ensure: present 
ntp::servers: '-' 
""" 

data = ruamel.yaml.round_trip_load(yaml_str) 
res = ruamel.yaml.round_trip_dump(data, indent=4, block_seq_indent=2, 
          explicit_start=True) 
assert res == yaml_str 

それはまた、私が追加したコメントを保持することに注意してください最初の配列要素。


あなたが「ゼロ」からこれを構築するが、改行を追加すると、通話がruamel.yamlに存在するためものではありませんすることができます

import ruamel.yaml 
from ruamel.yaml.tokens import CommentToken 
from ruamel.yaml.error import Mark 
from ruamel.yaml.comments import CommentedMap, CommentedSeq 


data = CommentedMap() 
data['classes'] = classes = CommentedSeq() 
classes.append('apache') 
classes.append('ntp') 

data['apache::first'] = 1 
data['apache::package_ensure'] = 'present' 
data['apache::port'] = 999 
data['apache::second'] = 2 
data['apache::service_ensure'] = 'running' 
data['ntp::bla'] = 'bla' 
data['ntp::package_ensure'] = 'present' 
data['ntp::servers'] = '-' 


m = Mark(None, None, None, 0, None, None) 
data['classes'].ca.items[1] = [CommentToken('\n\n', m, None), None, None, None] 
#      ^1 is the last item in the list 
data.ca.items['apache::service_ensure'] = [None, None, CommentToken('\n\n', m, None), None] 

res = ruamel.yaml.round_trip_dump(data, indent=4, block_seq_indent=2, 
          explicit_start=True) 
print(res, end='') 

あなたは#「なし(コメントとして改行を追加する必要があります')を改行の前の最後の要素、すなわち最後のリスト要素とapache::service_ensureマッピングエントリに追加します。別にあなたは本当にYAML 1.2 2005年からYAML 1.1(ほとんどの)およびない最新のリビジョンいるのみサポート2009

ワードプレスのページにあなたからPyYAMLとを使用したい場合は、自分自身に問う必要があることから、


リンク先は非常に深刻ではないようです(パッケージ名はPyYAML、正しい)。

+0

ありがとう、これは私が欲しいものです。私の場合、入力データは要求本体から生成され、次のようになります: '{u'apache :: package_ensure ':u'present'、u'apache :: first ':1、u'ntp :: u'app '、' u'ntp :: package_ensure ':u'present'、 'u'ntp: :サーバー ':u'-'、u'apache :: service_ensure ':u'running'、u'apache :: port ':999} '。そのdictから望ましいフォーマット(上記のような)を得る方法はありますか?または私はそれをさらに処理する必要がありますか? –

+0

空の行以外のものはすべて自明です。 'CommentedMap'インスタンス(' from ruamel.yaml.comments import CommentedMap')を作成し、必要な順番でキーに値を割り当ててから、そのインスタンスをダンプするだけです。私は空の行を追加するための詳細を調べなければならないでしょうが、大まかな正しいYAMLファイルを読み込んで肉付けする方が一般に簡単です。あなたは常に異なる値を持つ同じキーを持っていますか?または少なくとも空白行と分離を必要とする少なくとも3つのセクション? – Anthon

+0

ユーザは、異なるキーと設定値を選択することによって、UIからyamlファイルを生成しています。したがって、キーが異なる可能性があり、セクションの数も異なる可能性があります(3つ未満) –

関連する問題