pyyaml
поддерживает дамп литеральных или сложенных блоков.
Использование Representer.add_representer
определения типов:
class folded_str(str): pass
class literal_str(str): pass
class folded_unicode(unicode): pass
class literal_unicode(str): pass
Затем вы можете определить представители для этихтипы.Обратите внимание, что, хотя Gary решение отлично работает для юникода, вам может потребоваться дополнительная работа для правильной работы строк (см. реализация представления_str ).
def change_style(style, representer):
def new_representer(dumper, data):
scalar = representer(dumper, data)
scalar.style = style
return scalar
return new_representer
import yaml
from yaml.representer import SafeRepresenter
# represent_str does handle some corner cases, so use that
# instead of calling represent_scalar directly
represent_folded_str = change_style('>', SafeRepresenter.represent_str)
represent_literal_str = change_style('|', SafeRepresenter.represent_str)
represent_folded_unicode = change_style('>', SafeRepresenter.represent_unicode)
represent_literal_unicode = change_style('|', SafeRepresenter.represent_unicode)
Затем вы можете добавить эти представления в дампер по умолчанию:
yaml.add_representer(folded_str, represent_folded_str)
yaml.add_representer(literal_str, represent_literal_str)
yaml.add_representer(folded_unicode, represent_folded_unicode)
yaml.add_representer(literal_unicode, represent_literal_unicode)
... и проверить его:
data = {
'foo': literal_str('this is a\nblock literal'),
'bar': folded_unicode('this is a folded block'),
}
print yaml.dump(data)
результат:
bar: >-
this is a folded block
foo: |-
this is a
block literal
Использование default_style
Если вы заинтересованы в том, чтобы все строки соответствовали стилю по умолчанию, вы также можете использовать аргумент ключевого слова default_style
, например:
>>> data = { 'foo': 'line1\nline2\nline3' }
>>> print yaml.dump(data, default_style='|')
"foo": |-
line1
line2
line3
или для сложенных литералов:
>>> print yaml.dump(data, default_style='>')
"foo": >-
line1
line2
line3
или для двойных кавычек:
>>> print yaml.dump(data, default_style='"')
"foo": "line1\nline2\nline3"
Предостережения:
Вот пример того, чего вы можете не ожидать:
data = {
'foo': literal_str('this is a\nblock literal'),
'bar': folded_unicode('this is a folded block'),
'non-printable': literal_unicode('this has a \t tab in it'),
'leading': literal_unicode(' with leading white spaces'),
'trailing': literal_unicode('with trailing white spaces '),
}
print yaml.dump(data)
приводит к:
bar: >-
this is a folded block
foo: |-
this is a
block literal
leading: |2-
with leading white spaces
non-printable: "this has a \t tab in it"
trailing: "with trailing white spaces "
1) непечатаемым символам
См. Спецификацию YAML для экранированных символов ( Раздел 5.7 ):
Обратите внимание, что escape-последовательности интерпретируются только в скалярах с двойными кавычками.Во всех других скалярных стилях символ «\» не имеет специального значения, а непечатные символы недоступны.
Если вы хотите сохранить непечатные символы (например,TAB), вам нужно использовать скаляры с двойными кавычками.Если вы можете создать скаляр с буквальным стилем, и там есть непечатаемый символ (например, TAB), ваш дампер YAML несовместим.
Например, pyyaml
обнаруживает непечатныйсимвол \t
и использует стиль в двойных кавычках, даже если указан стиль по умолчанию:
>>> data = { 'foo': 'line1\nline2\n\tline3' }
>>> print yaml.dump(data, default_style='"')
"foo": "line1\nline2\n\tline3"
>>> print yaml.dump(data, default_style='>')
"foo": "line1\nline2\n\tline3"
>>> print yaml.dump(data, default_style='|')
"foo": "line1\nline2\n\tline3"
2) начальные и конечные пробелы
Еще одна полезная информация в спецификации:
Все начальные и конечные пробельные символы исключаются из содержимого
Это означает, что если ваша строка имеет начальный или конечный пробел, они не будут сохраненыв скалярных стилях, кроме двойных кавычек.Как следствие, pyyaml
пытается определить, что находится в вашем скаляре, и может вызвать двойные кавычки.