无法让 PyYAML 对象正确表示

Unable to get PyYAML objects to represent correctly

我正在使用 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 对象周围那些多余的尖括号是我需要删除的。

主要问题是您的标签不是以感叹号开头 标记。只需添加即可为您提供预期的输出。为了 参考参见 PyYAML 示例 Monster class.

额外的问题是:

  • yaml.org 上的常见问题解答指出,自 2006 年 9 月以来,推荐的文件扩展名 YAML 文件是 .yaml

  • PyYAML 转储(和加载)有一个流接口,但有一个 省略流的许多滥用便利选项,之后 输出被写入内存缓冲区,并以字符串形式返回。 使用它然后流出结果字符串使用:

    print(dump(yaml_list, ...))
    

    速度慢且内存效率低下。

  • 您为 RefTagSafeLoader,这很好,因为不需要去 unsafe with 默认的 PyYAML LoaderDumper。但后来你打电话 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)

给出:

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