2016-11-23 18 views
2

私はPythonコードで更新したい.yamlファイルを持っています。 のは、それがそのようなものに見えるとしましょう:Pythonを使ってyamlファイルの値を変更する

state: 'present' 

は私が状態を変更し、ファイルを保存し、コードを持っているしたいと思います。 私はこのような何かをしようとして失敗しています:

def set_state(state): 
    with open("file_to_edit.yaml", 'rw') as f: 
     doc = yaml.load(f) 
    doc['state'] = state 
    yaml.dump(f) 

私は、Python用の「YAML」パッケージを使用しています。

+0

何らかのエラーが発生していますか? – usr2564301

+1

いいえ、何も変更していません –

+0

何らかの理由でファイルに書き込んでいないようです –

答えて

4

問題はyaml.dumpが実際にファイルに書き込めないということです。代わりに、it returns the modified YAML as a stringをファイルに直接書き込む場合を除きます。

次は動作するはずです:

def set_state(state): 
    with open('file_to_edit.yaml') as f: 
     doc = yaml.load(f) 

    doc['state'] = state 

    with open('file_to_edit.yaml', 'w') as f: 
     yaml.dump(doc, f) 
+1

バム、それはトリックです!どうもありがとう! –

+0

YAML構造体とは何ですか? 'dump()'はあなたがすべきである 'stream'パラメータを指定しない限り、文字列(YAMLドキュメントを含む)を返します。返された文字列をファイルに書き込むことは、 'yaml.dump()'と悪いアドバイスを使うのに非効率的です(時間とメモリの使い方)。 – Anthon

1

私の推測では、現在の状態のあなたの機能は何もしないようだから、あなたは正しくインデントしていないと思います。 Python がインデントに気をつけます。

これを試してみてください:

def set_state(state): 
    with open("file_to_edit.yaml", 'rw') as f: 
     doc = yaml.load(f) 
    doc['state'] = state 
    yaml.dump(f) 
+1

ああ、インデントはきれいです..私はちょうどここにそれを貼り付けていませんでした.. –

0

をあなたは(それが結果を格納するための新しいファイルを作成します)次のことを試すことができます。

with open("output_file", 'a') as out: 
    with open("input_file", 'r') as f: 
     for line in f: 
      line = re.sub(r"state: present", "state: installed", line) 
      out.write(line) 
+1

私は同じファイルを好むが、ありがとう! –

1

何かする前に:あなた場合yaml.load()を使用することはありません原則として安全ではないので、にする必要はありません。この種のシンプルな構造(タグなし)の場合は、yaml.safe_load()(およびダンプ後にデータをsafe_loadできない場合は、対応するsafe_dump())を使用する必要があります。このうち

def dump(documents, stream=None, Dumper=Dumper, 
     default_style=None, default_flow_style=None, 
     canonical=None, indent=None, width=None, 
     allow_unicode=None, line_break=None, 
     encoding='utf-8', explicit_start=None, explicit_end=None, 
     version=None, tags=None) 

のみ最初のものは与えられる必要がある、あなたのdoc変数でなければなりません:

yaml.dump()は、次のシグネチャがあります。ストリームを指定しない場合、dump()はメモリ内のファイルオブジェクト(StringIOなど)にデータ構造を書き込み、書き込み後に値をstringとして返します。

だから、あなたができるものの:

with open("file_to_edit.yaml", 'w') as f: 
    f.write(yaml.safe_dump(doc)) 

これは非効率的であるとどのようにyaml.safe_dump()作品のほとんど理解を示しています。

ファイルを読み書きする場合は、ファイル内のインデックスを完全に切り捨ててください。書き込みのためにファイルを再オープンする方が安全であるように、これは通常、努力する価値はない:

def set_state(state): 
    file_name = "file_to_edit.yaml" 
    with open(file_name) as f: 
     doc = yaml.safe_load(f) 
    doc['state'] = state 
    with open(file_name, 'w') as f: 
     yaml.safe_dump(doc, f, default_flow_style=False) 

(もちろん、あなたがオリジナルを上書きを確認するときに、ファイル名の変数を作る

ので、あなたがすることはできませんミスタイプ)。

あなたがdefault_flow_style=Falseを指定しない場合は、あなたの出力は次のようになります。出力は、あなたの入力にpresentの周りに余分の引用符は含まれません

{state: deleted} 

default_style="'"も指定することができますが、これはまた引用符を約stateと置きます。
引用符をなくして出力を入力と同じようにしたい場合は、ruamel.yaml(免責事項私はそのパッケージの作者)を使用する必要があります。これは個々の文字列の引用符を保持し、YAML 1.2 YAML 1.1の代わりに)、あなたのファイルにコメントを保存します。

関連する問題