我有yaml数据,例如下面的输入,我需要将输出作为键值对
输入
a="""
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
code:
- '716'
- '718'
id:
- 488
- 499
"""
需要输入
{'code': ['716', '718'], 'id': [488, 499]}
默认构造函数给我一个错误。我尝试添加新的构造函数,现在它没有给我错误,但是我无法获取键值对。
仅供参考,如果我从Yaml中删除了!ruby/hash:ActiveSupport::HashWithIndifferentAccess
行,那么它将为我提供所需的输出。
def new_constructor(loader, tag_suffix, node):
if type(node.value)=='list':
val=''.join(node.value)
else:
val=node.value
val=node.value
ret_val="""
{0}
""".format(val)
return ret_val
yaml.add_multi_constructor('', new_constructor)
yaml.load(a)
output
"\n [(ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'code'), SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'716'), ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'718')])), (ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'id'), SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'488'), ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'499')]))]\n "
请提出建议。
答案 0 :(得分:1)
这不是使用PyYAML的解决方案,但我建议改为使用ruamel.yaml
。如果没有其他原因,它比PyYAML更加积极地维护。概述中的报价
许多针对PyYAML的错误,但从未得到解决,这些错误已在
ruamel.yaml
中修复
要加载该字符串,您可以
import ruamel.yaml
parser = ruamel.yaml.YAML()
obj = parser.load(a) # as defined above.
答案 1 :(得分:0)
我强烈建议您遵循@Andrew F的回答,但如果您 想知道为什么您的代码没有得到正确的结果,这是因为 您没有正确处理标签中标签下的节点 处理。
尽管节点的值是一个列表(包含键值对的元组),
您应该测试节点本身的类型(使用isinstance
)
然后将其移交给“常规”映射处理例程
标签在映射上:
import yaml
from yaml.loader import SafeLoader
a = """\
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
code:
- '716'
- '718'
id:
- 488
- 499
"""
def new_constructor(loader, tag_suffix, node):
if isinstance(node, yaml.nodes.MappingNode):
return loader.construct_mapping(node, deep=True)
raise NotImplementedError
yaml.add_multi_constructor('', new_constructor, Loader=SafeLoader)
data = yaml.load(a, Loader=SafeLoader)
print(data)
给出:
{'code': ['716', '718'], 'id': [488, 499]}
您不应该使用PyYAML的yaml.load()
,因为它被记录为潜在的不安全因素
最重要的是没有必要。只需将新的构造函数添加到SafeLoader
。