Как в Pyyaml ​​представить пустые строки и списки в блочном стиле?

Я добавил представителей для свернутых строк, литеральных строк, как указано в Любые библиотеки yaml в Python, которые поддерживают вывод длинных строк в виде блочных литералов или свернутых блоков?. Я также добавил представитель для печати списка в блочном стиле в выгруженном содержимом yaml.

Но проблема в том, что когда строка пуста, т. е. "" или список пуст, они отображаются в неблочном стиле в выгруженном содержимом YAML.

Как заставить дампер pyyaml ​​выводить "" пустые строки с ">" или "|" стиль и пустой список с flow_style=False в блочном стиле в сгенерированном содержимом YAML?


person rtnpro    schedule 04.06.2012    source источник


Ответы (1)


После небольшого исследования я могу вывести пустые строки в виде блочных литералов (стиль в '|>') в файле YAML, используя Pyyaml. Моя работа частично основана на Любые библиотеки yaml в Python, поддерживающие вывод длинных строк в виде блочных литералов или свернутых блоков?.

import yaml
from yaml.emitter import Emitter, ScalarAnalysis

class MyEmitter(Emitter):  
    def analyze_scalar(self, scalar):   
        # Empty scalar is a special case.
        # By default, pyyaml sets allow_block=False
        # I override this to set allow_block=True
        if not scalar:         
            return ScalarAnalysis(scalar=scalar, empty=True, multiline=False,
                allow_flow_plain=False, allow_block_plain=True,
                allow_single_quoted=True, allow_double_quoted=True,
                allow_block=True)   
        return super(MyEmitter, self).analyze_scalar(scalar)

# And I subclass MyDumper from MyEmitter and yaml.Dumper        
class MyDumper(yaml.Dumper, MyEmitter):
    pass
class folded_unicode(unicode): pass
class literal_unicode(unicode): pass

def folded_unicode_representer(dumper, data):
    return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='>')
def literal_unicode_representer(dumper, data):
    return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|')

yaml.add_representer(folded_unicode, folded_unicode_representer)
yaml.add_representer(literal_unicode, literal_unicode_representer)

# I test it now
d = {'foo': {'folded': folded_unicode(''), 'literal': literal_unicode('')}}
print yaml.dump(d, Dumper=MyDumper)

Вывод:

foo:
  folded: >
  literal: |

Однако я не могу найти способ сбросить пустой список в блочном стиле. Для этого я попробовал повозиться с yaml/emitter.py и понял, что мне нужен непустой список, чтобы сбрасывать его в блочном стиле.

В любом случае, эти усилия не прошли даром, скорее, это было довольно увлекательно :) Я надеюсь, что кому-то это может быть полезно или может быть чем-то поделиться.

person rtnpro    schedule 04.06.2012