SOに関するこれに関する質問はいくつかありますが、探しているものが見つかりませんでした。
pyyaml を使用して_.yml
_ファイルを読み取り(.load()
)、キーを変更または追加してから、もう一度書き込みます(.dump()
)。問題は、ダンプ後のファイル形式を保持したいのですが、変更されることです。
たとえば、キー_en.test.index.few
_を編集して、_"Bye"
_ではなく_"Hello"
_と言います。
Python:
_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 )
_
Yaml:
前:
_en:
test:
new: "Bye"
index:
few: "Hello"
anothertest: "Something"
_
後:
_en:
anothertest: Something
test:
index:
few: Hello
new: Bye
_
同じ形式を保持する方法はありますか?(例えば、qoutesとorder)。これに間違ったツールを使用していますか?
元のファイルが完全に正しいわけではないかもしれませんが、それを制御することはできません(Ruby on Rails i18nファイル)。
どうもありがとうございました。
代わりに _ruamel.yaml
_ を使用します。
PyYAMLは 事実上無効 であり、数年前から存在しています。さらに複雑なことに、公式プロジェクトのホーム http://pyyaml.org は最近削除されたようです。このサイトは、PyYAML課題トラッカー、ドキュメント、およびダウンロードをホストしていました。これを書いている時点で、すべてはなくなっています。これは災難にほかなりません。オープンソースのちょうど別の日へようこそ。
_ruamel.yaml
_は アクティブに維持 です。 PyYAMLとは異なり、_ruamel.yaml
_は以下をサポートします。
yaml.dump()
を呼び出して、yaml.load()
:[への以前の呼び出しによってロードされた辞書をダンプする場合。 ____。]ruamel.yaml
_は、all入力フォーマットを巧みに尊重します。すべて。スタイル全体のエンチラーダ。文学的なシバン全体。 すべて_ruamel.yaml
_はPyYAMLフォークであり、したがってPyYAML APIに準拠しているため、既存のアプリケーションでPyYAMLから_ruamel.yaml
_に切り替えることは通常、このすべてのインスタンスを置き換えるのと同じくらい簡単です。
_# This imports PyYAML. Stop doing this.
import yaml
_
...これとともに:
_# This imports "ruamel.yaml". Always do this.
from ruamel import yaml
_
それだけです。
他の変更は必要ありません。 yaml.load()
およびyaml.dump()
関数は引き続き期待どおりに動作するはずです-YAML 1.2をサポートし、バグ修正を積極的に受け取るという追加の利点があります。
PyYamlとの後方互換性のために、yaml.load()
およびyaml.dump()
関数はデフォルトでラウンドトリップ保存を行いますnot。これを行うには、明示的に渡します:
yaml.load()
へのオプションの_Loader=ruamel.yaml.RoundTripLoader
_キーワードパラメータ。yaml.dump()
へのオプションの_Dumper=ruamel.yaml.RoundTripDumper
_キーワードパラメータ。_ruamel.yaml
_ documentation から親切に「借りた」例:
_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='')
_
完了です。コメント、順序付け、引用、空白はそのまま保存されます。
常に_ruamel.yaml
_を使用します。 PyYAMLを使用しないでください。 _ruamel.yaml
_は生きています。 PyYAMLは、PyPiの成形用の納骨堂で腐敗している悪臭を放つ死体です。
長生き_ruamel.yaml
_。
最初の
辞書データを表すには、次のコードを使用します。
mapping = list(mapping.items())
try:
mapping = sorted(mapping)
except TypeError:
pass
順序が変更される理由です
2番目
スカラー型の表示方法に関する情報(二重引用符付きまたはなし)は、読み取り時に失われます(これはライブラリの主要なアプローチです)
概要
「Dumper」に基づいて独自のクラスを作成し、「represent_mapping」メソッドをオーバーロードして、辞書の表示方法を変更できます。
スカラーの二重引用符に関する情報を保存するには、「ローダー」に基づいて独自のクラスを作成する必要がありますが、他のクラスに影響を与え、それを困難にすることを恐れています
私の場合、値に_"
_または_{
_が含まれる場合は_}
_が必要です。例えば:
_ en:
key1: value is 1
key2: 'value is {1}'
_
これを実行するには、モジュールrepresent_str()
をファイルPyYamlのファイルrepresenter.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
_で同じことを実行します