50

SOでこれについていくつか質問があることは知っていますが、探していたものが見つかりませんでした。

pyyamlを使用してファイルを読み取り ( .load()) 、キーを変更または追加してから、再度.yml書き込みます ( )。.dump()問題は、ダンプ後のファイル形式を維持したいのですが、変更されることです。

たとえば、代わりにen.test.index.few言うようにキーを編集します"Bye""Hello"

パイソン:

with open(path, 'r', encoding = "utf-8") as yaml_file:
    self.dict = pyyaml.load(yaml_file)

次に、キーを変更した後:

with open(path, 'w', encoding = "utf-8") as yaml_file:
    dump = pyyaml.dump(self.dict, default_flow_style = False, allow_unicode = True, encoding = None)
    yaml_file.write( dump )

ヤムル:

前:

en:
  test:
    new: "Bye"
    index:
      few: "Hello"
  anothertest: "Something"

後:

en:
  anothertest: Something
  test:
    index:
      few: Hello
    new: Bye

同じ形式を維持する方法はありますか?たとえば、qoutes と order. これに間違ったツールを使用していますか?

元のファイルが完全に正しいわけではないことはわかっていますが、それを制御することはできません (Ruby on Rails i18n ファイルです)。

どうもありがとうございました。

4

3 に答える 3

94

以下でruamel.yamlは、代わりに使用されます。

ruamel.yaml積極的に維持されています。PyYAML とは異なり、以下をruamel.yamlサポートします。

  • YAML <= 1.2。PyYAML は YAML <= 1.1 のみをサポートします。YAML 1.2はいくつかのエッジ ケースで YAML 1.1 との後方互換性を意図的に壊しているため、これは非常に重要です。これは通常、悪いことです。この場合、これは YAML 1.2 を JSON の厳密なスーパーセットにします。YAML 1.1 はJSON の厳密なスーパーセットではないため、これは良いことです。
  • 往復保存。yaml.dump()への以前の呼び出しによってロードされたディクショナリをダンプするために呼び出す場合yaml.load():
    • PyYAML は、コメント、順序付け、引用、空白など、すべての入力フォーマットを単純に無視します。非常に多くのデジタルごみのように、最も近い使用可能なビット バケットに廃棄されます。
    • ruamel.yamlすべての入力フォーマットを巧みに尊重します。すべての。全体の文体エンチラーダ。全体の文学シバン。全て。

ライブラリの移行

PyYAML からruamel.yaml既存のアプリケーションへの切り替えは、通常、ライブラリのインポートを次のように変更するのと同じくらい簡単です。

from ruamel import yaml

これruamel.yamlは、PyYAML API に準拠する PyYAML フォークであるため機能します。

他の変更は必要ありません。および関数は引き続き期待どおりに動作するはずですyaml.load()yaml.dump()

往復の保存とそれができること

PyYaml との下位互換性のために、関数yaml.load()yaml.dump()関数はデフォルトでラウンドトリップ保存を実行しません。そのためには、明示的に次を渡します。

  • へのオプションのLoader=ruamel.yaml.RoundTripLoaderキーワード パラメータyaml.load()
  • へのオプションのDumper=ruamel.yaml.RoundTripDumperキーワード パラメータyaml.dump()

ruamel.yamlドキュメントから親切に「借りた」例:

import ruamel.yaml

inp = """\
# example
name:
  # Yet another Great Duke of Hell. He's not so bad, really.
  family: TheMighty
  given: Ashtaroth
"""

code = ruamel.yaml.load(inp, Loader=ruamel.yaml.RoundTripLoader)
code['name']['given'] = 'Astarte'  # Oh no you didn't.

print(ruamel.yaml.dump(code, Dumper=ruamel.yaml.RoundTripDumper), end='')

されております。コメント、順序付け、引用、空白はそのまま保持されるようになりました。

于 2016-04-21T05:32:18.317 に答える
5

私の場合、"値に a{または aが含まれている場合}、それ以外の場合は何もありません。例えば:

 en:
   key1: value is 1
   key2: 'value is {1}'

represent_str()これを実行するには、モジュール PyYaml のファイル renamer.py から関数をコピーし、文字列に{またはが含まれる場合は別のスタイルを使用します}

def represent_str(self, data):
    tag = None
    style = None
    # Add these two lines:
    if '{' in data or '}' in data:
        style = '"'
    try:
        data = unicode(data, 'ascii')
        tag = u'tag:yaml.org,2002:str'
    except UnicodeDecodeError:
        try:
            data = unicode(data, 'utf-8')
            tag = u'tag:yaml.org,2002:str'
        except UnicodeDecodeError:
            data = data.encode('base64')
            tag = u'tag:yaml.org,2002:binary'
            style = '|'
    return self.represent_scalar(tag, data, style=style)

コードで使用するには:

import yaml

def represent_str(self, data):
  ...

yaml.add_representer(str, represent_str)

この場合、キーと値の間に違いはなく、それで十分です。キーと値に別のスタイルが必要な場合は、関数で同じことを実行しますrepresent_mapping

于 2016-10-14T13:44:23.940 に答える