2016-01-05 3 views
5

PyYAMLを使用して、環境ごとに設定ファイルを準備します。しかし、私たちのYAMLブロックは完全性を失います。解析されたドキュメントをダンプするときにYAMLブロック構造を保持することは可能ですか?

付け

pubkey: | 
    -----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 
    EsUgJHXcpw7OPxRrCQIDAQAB 
    -----END PUBLIC KEY----- 

...のpython3を使用して、このプログラムを実行...

import yaml 

with open('input.yml', mode='r') as f: 
    parsed = yaml.safe_load(f) 

with open('output.yml', mode='w') as f: 
    yaml.dump(parsed, f) 

は...生産input.yml ...このoutput.yml ...

pubkey: '-----BEGIN PUBLIC KEY----- 

    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 

    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 

    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 

    EsUgJHXcpw7OPxRrCQIDAQAB 

    -----END PUBLIC KEY----- 

    ' 

PyYAMLを使ってブロックの構造を保存することは可能ですか?

答えて

5

はいそれはpyyamlで可能ですが、safe_loadによって使用され、少なくともスキャナ、パーサおよびコンストラクタの独自の強化されたバージョンを提供する必要があり、エミッタ、シリアライザとRepresenterは、ダンプ、 によっておよび提供することで、使用しません特殊な文字列のようなクラスで、オリジナルの書式設定に関する情報を保持します。

これはruamel.yaml免責事項:私はそのパッケージの作者午前)に添加したものの一部であることがPyYAMLとから得られたとして、まだ同様のセットアップを保持します。 ruamel.yaml使用:

import ruamel.yaml as yaml 

yaml_str = """\ 
pubkey: | 
    -----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 
    EsUgJHXcpw7OPxRrCQIDAQAB 
    -----END PUBLIC KEY----- 
""" 

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader) 
print(yaml.dump(data, Dumper=yaml.RoundTripDumper, indent=4)) 

があなたに与えます:

pubkey: | 
    -----BEGIN PUBLIC KEY----- 
    MIGfMA0GCSq7OPxRrQEBAQUAA4GNADCBiQKBgQCvRVUKp6pr4qBEnE9lviuyfiNq 
    QtG/OCyBDXL4Bh3FmUzfNI+Z4Bh3FmUx+z2n0FCv/4BpgHTDl8D95NPopWVo1RH2 
    UfhyMd6dQ/x9T5m+y38JMzmSVAk+Fqu8ya18+yQVOEyEIx3Gxpsgegow33gcxfjK 
    EsUgJHXcpw7OPxRrCQIDAQAB 
    -----END PUBLIC KEY----- 

少なくともPythonの2.7と3.5と。

indent=4がインデント二つの空間にRoundTripDumperデフォルトとして必要であり、 ファイルの元のインデントは、(そうしない再インデントYAMLファイルを容易に)保存されていません。

ruamel.yamlに切り替えることができない場合は、そのソースを使用して必要な変更をすべて抽出できるはずですが、可能であればコメントやマージキー名の保存などの他の機能も使用できます。

+0

よくできました。私はpyyamlソースを掘り下げて、余分な改行が追加されている場所を見つけようとしていたので、うまくいけばそれをサブクラス化することができましたが、寝る前に運がありません。 – MattDMo

+0

@MattDMo "normal"ダンプの余分な行は、文字列に改行が含まれているためです。特殊文字で文字列を表現する方法は複数あり、PyYAMLでこれを選択する方法もあります。選択は、スカラーの解析に基づいて 'emitter.choose_scaler_style()'にありますが、実際にどのように動作するかは本当に追跡が難しいです。ダンピングするときに、読んだり、ノードスタイルを明示的に設定したりするという特別なタイプを作ることで、すべてを回避しています。 – Anthon

+0

私は 'ruamel.yaml'をインストールしました。ちょっとだけ遊んでいました。とてもいいです。 2つの素早い(トピック以外の)質問:名前はどこから来たのですか?YAML 1.2をサポートする計画はありますか?最初の '%YAML 1.2'のようなファイルがいくつかあるので、私は尋ねます。私は仕様間の違い(1.2仕様の第1部を読んだ後でさえ)、あるいはファイルが1.2の新しい機能を利用するかどうかを知りません - それらは主に文字列かブール値(オブジェクトなし)。 http://bit.ly/1JXLVbf – MattDMo

関連する問題