Pyyaml嵌套对象

时间:2017-05-24 11:35:30

标签: python pyyaml

我想用PyYaml解释以下YAML字符串:

      - !Table
        header:
          - !Column
            - !Paragraph
              text: 'header1'
          - !Column 
            - !Paragraph
              text: 'header2'

我有从yaml.YAMLObject类继承的Table和Paragraph类。但我不知道如何处理!Column标签?此标记应仅作为命名数组标记处理。

当我想从yaml.load()函数构建对象时,出现以下错误:

yaml.constructor.ConstructorError: could not determine a constructor 
for the tag '!Column'
in "<unicode string>", line 19, column 17:
              - !Column
                ^

1 个答案:

答案 0 :(得分:0)

使用yaml.YAMLObject时存在两个问题:

  • 除了默认yaml.Loader之外,使用除yaml.load()之外的任何内容都是不透明的,除非您现在和将来都能完全控制输入,否则您不应该使用它。< / LI>
  • 您不能将它用于由标量或序列组成的节点的对象。只能使用映射。

您的!Table!Paragraph是映射节点。但是你的!Column是一个序列,你明确需要为它做一个构造函数:

import sys
from ruamel import yaml

yaml_str = """\
- !Table
  header:
    - !Column
      - !Paragraph
        text: 'header1'
    - !Column
      - !Paragraph
        text: 'header2'

"""

class Table(yaml.YAMLObject):
    yaml_tag = u'!Table'
    pass


class Paragraph(yaml.YAMLObject):
    yaml_tag = u'!Paragraph'
    pass

def column_constructor(loader, node):
    return loader.construct_sequence(node)

yaml.add_constructor('!Column', column_constructor)


data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout, default_flow_style=False)

打印:

- !Table
  header:
  - - !Paragraph
      text: header1
  - - !Paragraph
      text: header2

和(因为我使用ruamel.yaml,也是UnsafeLoaderWarning)。

如果您希望输出包含!Column,那么您应该创建一个python类Column(list)并让column_constructor给出该类型,并另外为Column编写一个表示符并将其添加到装载程序。