YAMLで参照する唯一の方法は、&
(アンカー)と*
(エイリアス)を使用することです。これらが機能するには、同じYAML文書になければなりません。以下は(これはmerge key特徴に基づいているが、通常のオブジェクト参照は、同じ制限を持って)動作しません:
import ruamel.yaml
yaml_str = """\
a: &BASE { x: 1, y: 2}
---
b:
<< : *BASE
z: 3
"""
for data in ruamel.yaml.load_all(yaml_str):
print(data)
は、「BASE」が見つからなかったことを作曲エラーをスロー。ドキュメントセパレータ---
を削除しても問題ありません。
原則として、2つのドキュメントを連結することができます。エイリアスを含むドキュメントを別々に読み込むことは、アンカーを含むドキュメントと連結しなければ実行できません。
さらに、すべてのドキュメントがトップレベルにマッピングまたはシーケンスを持つ必要があるという警告があります。マッピングに
- &BASE a
- b
:シーケンスを組み合わせたい場合
結果がロード可能ではありません。
示されているように、トップレベルのタイプがすべてのファイルで同じ場合、YAMLファイルをロードしてメモリに組み込むことはできません。私。
- &CENTER { x: 1, y: 2 }
- &LEFT { x: 0, y: 2 }
- &BIG { r: 10 }
- &SMALL { r: 1 }
2.yaml
:
# Explicit keys
-
x: 1
y: 2
r: 10
label: center/big
3.yaml
:
# Merge one map
-
<< : *CENTER
r: 10
label: center/big
4.yaml
:
# Merge multiple maps
-
<< : [ *CENTER, *BIG ]
label: center/big
012マージキードキュメント分割の例
1.yaml
に与えられました
5.yaml
:
# Override
-
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big
あなたは個別のYAMLファイルの使用load()
ことはできませんし、それらを組み合わせた:
import ruamel.yaml
import glob
data = []
for file_name in sorted(glob.glob('*.yaml')):
data.append(ruamel.yaml.load(open(file_name)))
print(ruamel.yaml.dump(data, allow_unicode=True))
(その上2.yaml
場合などに働くだろう
class CombinedOpenForReading(object):
def __init__(self, file_names):
self._to_do = file_names[:]
self._fp = None
def __enter__(self):
return self
def __exit__(self, exception_type, exception_value, exception_traceback):
if self._fp:
self._fp.close()
def read(self, size=None):
res = ''
while True:
if self._fp is None:
if not self._to_do:
return res
else:
self._fp = open(self._to_do.pop(0))
if size is None:
data = self._fp.read()
else:
data = self._fp.read(size)
if size is None or not data:
self._fp.close()
self._fp = None
res += data
if size is None:
continue
size -= len(data)
if size == 0:
break
return res
行うには:
import ruamel.yaml
import glob
with CombinedOpenForReading(sorted(glob.glob('*.yaml'))) as fp:
data = ruamel.yaml.round_trip_load(fp)
assert data[6]['r'] == 10
print(ruamel.yaml.dump(data, Dumper=ruamel.yaml.RoundTripDumper))
あなたがプログラムの外のファイルを連結したくない場合は、 このクラスを使用することができます)
を別名を持っていませんでした取得する:
- &CENTER {x: 1, y: 2}
- &LEFT {x: 0, y: 2}
- &BIG {r: 10}
- &SMALL {r: 1}
# Explicit keys
- x: 1
y: 2
r: 10
label: center/big
# Merge one map
- <<: *CENTER
r: 10
label: center/big
# Merge multiple maps
- <<: [*CENTER, *BIG]
label: center/big
# Override
- <<: [*BIG, *LEFT, *SMALL]
x: 1
label: center/big
(正しい順序でファイルを手渡す必要があるため、ソート。ファイルの末尾に改行があることを確認してください。そうしないと予期しないエラーが発生する可能性があります)。
あなたの注意点では、BASEと* BASEは同じ種類のもの(シーケンス対マッピング)でなければなりませんか?私はそれが問題だとは気付かなかったが、それは問題ではない。 1つのファイルで複数のドキュメントを使用する予定はありません。 1つのドキュメントで複数のファイルを使用する予定です。 –
ああ、あなたがファイルをマージできるようにするには、それらのファイルのトップタイプが同じでなければならないということです。はい、それは問題ではありません。 –
@BrianPostowはい、一番上のタイプは同じファイルで – Anthon