Конец Yaml ("...") всегда сбрасывается, даже если yaml.explicit_end = False - PullRequest
2 голосов
/ 09 июля 2019

Мне интересно, действительно ли это ошибка или намерение, но в любом случае.

Почему вывод одного значения всегда включает явное завершение YAML?

import sys
from ruamel.yaml import YAML
yaml=YAML()
yaml.explicit_end=False
yaml.dump(1, sys.stdout)

Производит

1
...

Можно ли как-то легко пропустить ?

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Причина добавления маркера конца документа (...) заключается в том, что число сбрасывается в виде скаляра plain на корневом уровне документа.То же самое происходит, если вы выгружаете строку (при условии, что строка может быть выгружена без кавычек без неправильного толкования, то есть строка, состоящая только из цифр, должна быть заключена в кавычки, чтобы не рассматриваться как целое число).

Без документа-end-marker, при загрузке из потока, анализатор не будет знать, завершен ли документ, или поток только ожидает заполнения.Document-end-marker устраняет эту неоднозначность, так что это сделано намеренно, но, например, при разборе файла (вместо общего потока) это можно и будет выполнять путем проверки конца файла.

Есть несколько способов обойти это, один из них - преобразовать вывод:

import sys
import ruamel.yaml

def strip_document_end_marker(s):
   if s.endswith('...\n'):
       return s[:-4]

yaml = ruamel.yaml.YAML()
yaml.dump("abc", sys.stdout, transform=strip_document_end_marker)

, что дает:

abc

Выше также должно работать с dump_all для нескольких документов(и последний является простым скаляром корневого уровня).

Еще один способ добиться этого - сбросить атрибут open_ended после записи простого значения:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()

def wp(self, *args, **kw):
    self.write_plain_org(*args, **kw)
    self.open_ended = False

yaml.Emitter.write_plain_org = yaml.Emitter.write_plain
yaml.Emitter.write_plain = wp
yaml.dump("abc", sys.stdout)

, что также дает:

abc
1 голос
/ 09 июля 2019

Я не уверен в причине, но yaml.dump("1", sys.stdout) не печатает маркер окончания документа.

Похоже, что сериализатор добавляет три точки ( маркер конца документа ) добавляется, когда сериализатор получает не повторяемое значение:

dump(1, stream=sys.stdout)
dump([1], stream=sys.stdout)
dump(datetime.datetime.now(), stream=sys.stdout)
dump("1", stream=sys.stdout)

Печать:

1
...
[1]
2019-07-09 12:45:27.013202
...
'1'

Таким образом, простой обходной путь - преобразовать ваши значения в строку перед тем, как их выгружать (если это возможно) ...

...