Python 从 YAML 解析类

gt6*_*89b 6 python yaml pyyaml python-2.7

我正在尝试输出然后从 YAML 解析回以下内容

import numpy as np
class MyClass(object):
    YAMLTag = '!MyClass'

    def __init__(self, name, times, zeros):
        self.name   = name
        self._T     = np.array(times)
        self._zeros = np.array(zeros)
Run Code Online (Sandbox Code Playgroud)

YAML 文件看起来像

!MyClass:
  name: InstanceId
  times: [0.0, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0]
  zeros: [0.03, 0.03, 0.04, 0.03, 0.03, 0.02, 0.03]
Run Code Online (Sandbox Code Playgroud)

为了编写,我在类中添加了两个方法

def toDict(self):
    return {'name'  : self.name,
            'times' : [float(t) for t in self._T],
            'zeros' : [float(t) for t in self._zeros]}
@staticmethod
def ToYAML(dumper, data):
    return dumper.represent_dict({data.YAMLTag : data.toDict()})
Run Code Online (Sandbox Code Playgroud)

并阅读,方法

@staticmethod
def FromYAML(loader, node):
    nodeMap = loader.construct_mapping(node)
    return MyClass(name  = nodeMap['name'],
                   times = nodeMap['times'],
                   zeros = nodeMap['zeros'])
Run Code Online (Sandbox Code Playgroud)

在YAML 文档之后,我在同一个 Python 文件中添加了以下代码片段myClass.py

import yaml

yaml.add_constructor(MyClass.YAMLTag, MyClass.FromYAML)
yaml.add_representer(MyClass,         MyClass.ToYAML)
Run Code Online (Sandbox Code Playgroud)

现在,编写似乎可以正常工作,但是读取 YAML、代码

loader.construct_mapping(node)
Run Code Online (Sandbox Code Playgroud)

似乎返回带有空数据的字典:

{'zeros': [], 'name': 'InstanceId', 'times': []}
Run Code Online (Sandbox Code Playgroud)

我应该如何修复阅读器才能正确执行此操作?或者也许我没有写出一些东西,对吗?我花了很长时间查看 PyYAML 文档并调试包的实现方式,但无法找到解析复杂结构的方法,而我似乎找到的唯一示例有一个可以轻松解析的单行类。


相关:YAML解析和Python


更新

手动解析节点如下:

name, times, zeros = None, None, None
for key, value in node.value:
    elementName = loader.construct_scalar(key)
    if elementName == 'name':
        name = loader.construct_scalar(value)
    elif elementName == 'times':
        times = loader.construct_sequence(value)
    elif elementName == 'zeros':
        zeros = loader.construct_sequence(value)
    else:
        raise ValueError('Unexpected YAML key %s' % elementName)
Run Code Online (Sandbox Code Playgroud)

但问题仍然存在,有没有一种非手动的方式来做到这一点?

tin*_*ita 1

代替

nodeMap = loader.construct_mapping(node)
Run Code Online (Sandbox Code Playgroud)

尝试这个:

nodeMap = loader.construct_mapping(node, deep=True)
Run Code Online (Sandbox Code Playgroud)

另外,您的 YAML 文件中有一个小错误:

!MyClass:
Run Code Online (Sandbox Code Playgroud)

最后的冒号不属于那里。