无法获取PyYAML对象以正确表示

时间:2019-01-05 16:27:25

标签: python yaml pyyaml

我正在使用PyYaml重新生成YAML文件,但是在转储的输出周围有不需要的尖括号:

YAML源文件:

 Outputs:
  HarvestApi:
    Description: URL for application
    Value: !Ref LocationRef
    Export:
      Name: HarvestApi

并且python文件应该只是解析然后转储YAML:

#!/usr/bin/env python3.6

import yaml
import sys

class RefTag(yaml.YAMLObject):
  yaml_tag = u'Ref'
  def __init__(self, text):
    self.text = text
  def __repr__(self):
    return "%s( text=%r)" % ( self.__class__.__name__, self.text)
  @classmethod
  def from_yaml(cls, loader, node):
    return RefTag(node.value)
  @classmethod
  def to_yaml(cls, dumper, data):
    return dumper.represent_scalar(cls.yaml_tag, data.text)
yaml.SafeLoader.add_constructor('!Ref', RefTag.from_yaml)
yaml.SafeDumper.add_multi_representer(RefTag, RefTag.to_yaml)

yaml_list = None
with open("./yaml-test.yml", "r")  as file:  
  try:
    yaml_list = yaml.safe_load(file)
  except yaml.YAMLError as exc:
    print ("--", exc)
    sys.exit(1)

print (yaml.dump(yaml_list, default_flow_style=False))

但是输出以下内容:

Outputs:
  HarvestApi:
    Description: URL for application
    Export:
      Name: HarvestApi
    Value: !<Ref> 'LocationRef'

我需要删除Ref对象周围那些多余的尖括号。

1 个答案:

答案 0 :(得分:1)

主要问题是您的标签不是以惊叹号开头 标记。只需添加,即可获得预期的输出。对于 参考,请参见PyYAML示例 Monster 课。

其他有问题的东西是:

  • 从2006年9月开始,yaml.org上的常见问题解答就指出了针对 YAML文件为it('should display if true ...')

  • PyYAML转储(和加载)具有流接口,但具有 大量滥用便利选项而忽略了流,之后 输出将写入作为字符串返回的内存缓冲区。 然后使用它来流式生成结果字符串:

    it('shouldn't' display if false)

    速度慢且内存效率低。

  • 您在.yaml上为print(dump(yaml_list, ...)) 注册了装载程序和倾卸程序 RefTag,这很好,因为不必担心 默认的PyYAML SafeLoaderLoader。但是你打电话 Dumper,而不是yaml.dump()。前者有效,但 使用后者更好,因为它会抱怨未注册 数据结构中的对象(如果有的话,当然不是 输入,您现在正在使用)。

因此将其更改为:

yaml.safe_dump()

给出:

#!/usr/bin/env python3.6

import yaml
import sys

class RefTag(yaml.YAMLObject):
  yaml_tag = u'!Ref'
  def __init__(self, text):
    self.text = text
  def __repr__(self):
    return "%s( text=%r)" % ( self.__class__.__name__, self.text)
  @classmethod
  def from_yaml(cls, loader, node):
    return RefTag(node.value)
  @classmethod
  def to_yaml(cls, dumper, data):
    return dumper.represent_scalar(cls.yaml_tag, data.text)

yaml.SafeLoader.add_constructor('!Ref', RefTag.from_yaml)
yaml.SafeDumper.add_multi_representer(RefTag, RefTag.to_yaml)

yaml_list = None
with open("./yaml-test.yaml", "r")  as file:  
  try:
    yaml_list = yaml.safe_load(file)
  except yaml.YAMLError as exc:
    print ("--", exc)
    sys.exit(1)

yaml.safe_dump(yaml_list, sys.stdout, default_flow_style=False)