2016-07-14 11 views
4

I下記のYAMLファイルを持っている:私はPyYAMLとでそれを読んで、それを再度ダンプPyYAMLとし、文字列の引用符を使用してのみ

--- 
my_vars: 
    my_env: "dev" 
    my_count: 3 

、私は次のような出力が得られます。

--- 
my_vars: 
    my_env: dev 
    my_count: 3 

コード問題になっている:

with open(env_file) as f: 
    env_dict = yaml.load(f) 
    print(yaml.dump(env_dict, indent=4, default_flow_style=False, explicit_start=True)) 
私は default_styleパラメータを使用してみました

with open(env_file) as f: 
    env_dict = yaml.load(f) 
    print(yaml.dump(env_dict, indent=4, default_flow_style=False, explicit_start=True, default_style='"')) 

しかし、今私が手:

--- 
"my_vars": 
    "my_env": "dev" 
    "my_count": !!int "3" 

私はYAMLファイル内の変数名についての仮定を作るせずに元の書式、を保つために行うには何が必要ですか?

+0

なぜファイルを印刷しないのですか?ファイル自体ではなく、印刷しているもののソースとして辞書を使用することは重要ですか? – Nobilis

+0

将来、辞書に追加のキーを追加しますが、レイアウトは保存する必要があります。 –

答えて

1

右、そうthis answerから重く借りて、あなたはこのような何か行うことができます:それは、同様のキーを引用しますので

import yaml 

# define a custom representer for strings 
def quoted_presenter(dumper, data): 
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"') 

yaml.add_representer(str, quoted_presenter) 


env_file = 'input.txt' 
with open(env_file) as f: 
    env_dict = yaml.load(f) 
    print yaml.dump(env_dict, default_flow_style=False) 

をしかし、これは単なる辞書ですべての文字列タイプで、それをオーバーロード、値だけではありません。

それは印刷されます。

"my_vars": 
    "my_count": 3 
    "my_env": "dev" 

はこれが何をしたいですか?変数名の意味がわからない場合は、キーを意味しますか?

+0

これはすでに私に多くの助けをくれました:-)どのように私はキーではなく、値にのみ適用することができますまだよく分かりません。 –

+0

余裕があれば、yamlの[documentation](http:// pyyaml。org/wiki/PyYAMLDocumentation#Constructorsrepresentersresolvers)を使用して、表現を作成する方法とYAMLのタグ[ここ](http://www.yaml.org/spec/1.2/spec.html)を徹底的に読みます。 PyYamlのフォークについて議論し、元のフォーマットを維持することについても言及する[この回答](http://stackoverflow.com/questions/20805418/pyyaml-dump-format)も参考になるかもしれません。 – Nobilis

3

ほとんどのYAML 1.1(2005)を実装するPyYAMLを使用する代わりに、後方互換性のあるruamel.yamlパッケージを使用してYAML 1.2(2009年リリース)を使用するように更新することをお勧めします。 (免責事項:私はそのパッケージの作者です)。

ラウンドトリップYAMLファイルのロード時に次に、あなただけのpreserve_quotes=Trueを指定:

import sys 
import ruamel.yaml 

yaml_str = """\ 
--- 
my_vars: 
    my_env: "dev" # keep "dev" quoted 
    my_count: 3 
""" 

data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True) 
ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True) 

(保存コメントを含む)出力:文字列スカラーをロードした後

--- 
my_vars: 
    my_env: "dev" # keep "dev" quoted 
    my_count: 3 

になります引用の情報に対応できるようにするにはstringのサブクラスを使用しますが、その他の目的では通常の文字列のように動作します。このような文字列を置換する場合は、 の文字列をこのサブクラスにキャストする必要があります(DoubleQuotedScalarStringからruamel.yaml.scalarstring)。

デフォルトでruamel.yamlをラウンドトリップすると、キーの順序(挿入による)が保持されます。

関連する問題