#python #yaml
#python #yaml
Вопрос:
У меня есть файл YAML, подобный приведенному ниже. Файл содержит некоторые специальные символы, такие как «—«, поэтому я не могу загрузить YAML в python с помощью yaml.load()
метода.
_engine: E1
_parameter:
- capacity:
- updated: 20200825
dependent: []
---
_engine: E2
_parameter:
- capacity:
- updated: 20200826
dependent: [D1,D2]
Как получилось, что содержимое YAML может быть изменено, как показано ниже, в python. Оно будет инкапсулировано под тегом mainData
and stage1
, stage2
и т.д. Средства для каждого «—«, stage<number value>
будут увеличиваться.
mainData:
stage1:
_engine: E1
_parameter:
- capacity:
- updated: 20200825
dependent: []
stage2:
_engine: E2
_parameter:
- capacity:
- updated: 20200826
dependent: [D1,D2]
Наконец, конечный поток также будет только YAML.
Комментарии:
1. Я думаю, вам придется вручную искать строку с тире и заменять ее. Затем проанализируйте результат как yaml. Вы пробовали это? Что произошло? Или вы могли бы выяснить, почему вам в первую очередь приходится иметь дело со сломанными файлами yaml.
2. Три дефиса обозначают новый документ в YAML. Смотрите yaml.info/learn/document.html
Ответ №1:
---
Является частью синтаксиса YAML. Короче говоря, это указывает на начало нового документа: https://yaml.org/spec/1.2/spec.html#YAML
Технически это фактически строка «конец директив», но если документ YAML не содержит никаких директив, то это фактически то же самое, что «начать новый документ». Это позволяет объединить несколько документов YAML вместе. С PyYAML вы можете перебирать все документы в файле с помощью yaml.load_all
. Если вы хотите связать индекс «stage» с каждым документом, просто выполните:
for stage_num, stage in enumerate(yaml.load_all(fileobj)):
...
Если вы хотите преобразовать это в один документ, вы могли бы сделать что-то вроде
stages = {}
for n, stage in enumerate(yaml.load_all(fileobj)):
stages[f'stage{n}'] = stage
Затем дамп stages
в файл YAML.
Но я хотел прояснить, что эти данные также уже имеют допустимую структуру, поэтому нет строгой необходимости их изменять.
Комментарии:
1. Я использую версию 3.4.4 и получаю ошибку со строкой stages[f’stage {n}’] = stage как недопустимый синтаксис
2. В Python 3.4 нет f-строк.
3. Python 3.4 также довольно давно больше не поддерживается. Вы должны обновиться по крайней мере до python 3.6.
4. Я просто попытался использовать load_all вместо load и попытался распечатать yaml. Вместо печати фактического «<загрузка объекта генератора
some_address
всех>5. это работает после преобразования o / p в list. например, print(список(yaml.load_all(yaml_data)))
Ответ №2:
Это должно сделать это
import itertools
with open('/path/to/input.yml') as infile, open('/path/to/output.yml', 'w') as outfile:
outfile.write("mainData:n")
stage = itertools.count(1)
for line in infile:
if not line.startswith('---'):
outfile.write(line)
continue
outfile.write(f"stage{next(stage)}:n")