2017-08-02 103 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)