2017-08-02 146 views
1

我正在尝试为我的类编写正确的from_yaml方法,以便在使用ruamel.yaml库加载YAML文件时能够反序列化回到它。将YAML反序列化回Python对象

让我们假设,在我的to_yaml类的方法,我回来是这样的:现在在反序列化方法

@classmethod 
def from_yaml(cls, constructor, node): 
    dict_representation = constructor.construct_mapping(node, deep=True) 

有了这个

@classmethod 
def to_yaml(cls, dumper, data): 
    dict_representation = { 
     'foo': data.foo, 
     'bar': data.bar 
    } 

    return dumper.represent_mapping(cls.yaml_tag, dict_representation) 

我得到TypeError

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-6-782b00e19bec> in <module>() 
----> 1 dict_representation = yaml.constructor.construct_mapping(node, deep=True) 

/home/**/.envs/myenv/local/lib/python2.7/site-packages/ruamel/yaml/constructor.pyc in construct_mapping(self, node, maptyp, deep) 
    1186       "found unhashable key", key_node.start_mark) 
    1187    value = self.construct_object(value_node, deep=deep) 
-> 1188    self.check_mapping_key(node, key_node, maptyp, key, value) 
    1189 
    1190    if key_node.comment and len(key_node.comment) > 4 and \ 

/home/**/.envs/myenv/local/lib/python2.7/site-packages/ruamel/yaml/constructor.pyc in check_mapping_key(self, node, key_node, mapping, key, value) 
    241  def check_mapping_key(self, node, key_node, mapping, key, value): 
    242   # type: (Any, Any, Any, Any, Any) -> None 
--> 243   if key in mapping: 
    244    if not self.allow_duplicate_keys: 
    245     args = [ 

TypeError: argument of type 'NoneType' is not iterable 

事实上,试图在经验上做到这一点,在交互tive外壳:

import ruamel.yaml 
yaml = ruamel.yaml.YAML() 
dd = {'foo': 'foo'} 
node = yaml.representer.represent_mapping('!dd', dd) 
dict_representation = yaml.constructor.construct_mapping(node) 

引发相同的异常。我在这里错过了什么?

+0

如果您发布异常的完整堆栈跟踪以及您正在使用的yaml库的名称,那么人们可以更容易地为您提供帮助。 – Vasil

回答

1

为了往返工作,construct_mapping()RoundTripConstructor()需要得到获得通过实际映射典型实例,所以像注释可从节点采取并连接到该实例(通常是CommentedMap() )。在执行非往返加载时不需要额外的参数(因为那些不需要传递注释信息)。

该方法本来可以设计得更聪明,因为如果默认为None作为映射类型(如果未提供),并且这是您从中获取NoneType is not iterable异常的地方。

要开始与你的问题的最后的代码,你可以通过做调用一个简单的映射构造:

dict_representation = ruamel.yaml.constructor.SafeConstructor.construct_mapping(
    yaml.constructor, node) 

from_yaml()类的方法应该以同样的方式工作:

@classmethod 
def from_yaml(cls, constructor, node): 
    dict_representation = ruamel.yaml.constructor.SafeConstructor.construct_mapping(
     constructor, node, deep=True) 

尽管如果构建复杂类型(其中一些间接可访问的值可能引用此节点),应考虑使用两步创建过程:

@classmethod 
def from_yaml(cls, constructor, node): 
    dict_representation = dict() 
    yield dict_representation 
    d = ruamel.yaml.constructor.SafeConstructor.construct_mapping(
     constructor, node, deep=True) 
    dict_representation.update(d)