Вам не нужно создавать каждый тип, какой вы
нужно сделать, это сделать общую процедуру обработки тегов, которая смотрит на
тип узла, на котором находится тег (отображение, последовательность, скаляр), затем
создает такой узел как тип Ruby, к которому может быть прикреплен тег.
Я не знаю, как это сделать с Psych
и Ruby
, но вы указали
не является строгим требованием, и большая часть тяжелой работы
для этого вида кругового отключения в ruamel.yaml
для Python
(отказ от ответственности: я являюсь автором этого пакета).
Если это ваш вклад
файл input.yaml
:
Foo: !Bar baz
N1:
- !mytaggedmaptype
parm1: 3
parm3: 4
- !mytaggedseqtype
- 8
- 9
N2: &someanchor1
a: "some stuff"
b: 0.2e+1
f: |
within a literal scalar newlines
are preserved
N3: &someanchor2
c: 0x3
b: 4 # this value is not taken, as the first entry found is taken
['the', 'answer']: still unknown
{version: 28}: tested!
N4:
d: 5.000
<<: [*someanchor1, *someanchor2]
Тогда эта программа на Python (3):
import sys
from pathlib import Path
import ruamel.yaml
yaml_in = Path('input.yaml')
yaml_out = Path('output.yaml')
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
# uncomment next line if your YAML is the outdated version 1.1 YAML but has no tag
# yaml.version = (1, 1)
data = yaml.load(yaml_in)
# do your updating here
data['Foo'].value = 'hello world!' # see the first of the notes
data['N1'][0]['parm3'] = 4444
data['N1'][0].insert(1, 'parm2', 222)
data['N1'][1][1] = 9999
data['N3'][('the', 'answer')] = 42
# and dump to file
yaml.dump(data, yaml_out)
создает output.yaml
:
Foo: !Bar hello world!
N1:
- !mytaggedmaptype
parm1: 3
parm2: 222
parm3: 4444
- !mytaggedseqtype
- 8
- 9999
N2: &someanchor1
a: "some stuff"
b: 0.2e+1
f: |
within a literal scalar newlines
are preserved
N3: &someanchor2
c: 0x3
b: 4 # this value is not taken, as the first entry found is taken
['the', 'answer']: 42
{version: 28}: tested!
N4:
d: 5.000
<<: [*someanchor1, *someanchor2]
Обратите внимание:
вы можете обновить помеченные скаляры, сохранив тег на
скаляр, но так как вы заменяете такой скаляр своим назначением
(вместо обновления значения как со списками (последовательностями / массивами) или
дикты (отображения / хэши), вы не можете просто присвоить новое значение или
вы потеряете информацию о тегах, вам придется обновить атрибут .value
.
такие вещи, как якоря, слияния, комментарии, цитаты сохраняются, как и
специальные формы целых чисел (шестнадцатеричные, восьмеричные и т. д.) и числа с плавающей точкой.
Для последовательностей YAML, которые являются клавишами сопоставления, необходимо использовать кортеж
(('the', 'answer')
) вместо последовательности (['the', 'answer']
),
поскольку Python не допускает изменяемые ключи в отображениях. И для ЯМ
сопоставления, которые являются ключами сопоставления, вам нужно использовать неизменный
Mapping
от
collections.abc
.
(Я не уверен, поддерживает ли Psych такие действительные ключи YAML)
См. это , если вам нужно обновить привязанные / псевдонимные скаляры