2017-01-23 60 views

回答

1

有一種方法,雖然它的接口不能保證穩定。 由於這個原因以及缺少文檔,通常可以幫助您查看您的預期產出或其中的一小部分樣本的表示形式round_trip_loading()

您必須認識到,結構化節點(映射和序列)的表示的特殊版本需要註釋。對於將safe_load()作爲Python dict的映射,這是一個CommentedMap(),對於序列,它將作爲Python list加載,這是一個CommentedSeq()

這兩個類都可以擁有一個.ca屬性,該屬性持有結構節點之前可能發生的註釋,作爲鍵/值對之後的行尾註釋。項,在鍵值對或項之間的自己的行上,以及在節點的末尾。

這意味着你有任何dict或轉換list你有,需要評論(可通過常規comment_prep()來完成自動/遞歸例如),然後找到正確的點和方式附加的註釋。 由於評論操作例程尚未穩定,因此請確保包裝您的評論以添加例程以獲取更新的單個位置以備更新。

import sys 
from ruamel.yaml import round_trip_dump as rtd 
from ruamel.yaml.comments import CommentedMap, CommentedSeq 

# please note that because of the dict the order of the keys is undetermined 
data = dict(a=1, b=2, c=['x', 'y', dict(k='i', l=42, m='∞')]) 

rtd(data, sys.stdout) 
print('-' * 30) 


def comment_prep(base): 
    """replace all dict with CommentedMap and list with CommentedSeq""" 
    if isinstance(base, dict): 
     ret_val = CommentedMap() 
     for key in sorted(base): # here we force sorted order 
      ret_val[key] = comment_prep(base[key]) 
     return ret_val 
    if isinstance(base, list): 
     ret_val = CommentedSeq() 
     for item in base: 
      ret_val.append(comment_prep(item)) 
     return ret_val 
    return base 

data = comment_prep(data) 
data['c'][2].yaml_add_eol_comment('# this is the answer', key='l', column=15) 
rtd(data, sys.stdout) 

給出:

c: 
- x 
- y 
- k: i 
    m: ∞ 
    l: 42 
b: 2 
a: 1 
------------------------------ 
a: 1 
b: 2 
c: 
- x 
- y 
- k: i 
    l: 42  # this is the answer 
    m: ∞ 

文件test_comment_manipulation.py,有一些更多的例子,是一個很好的地方,留意(如界面發生變化,因此將在該文件中的測試)。

+0

可以當然直接創建,而不是第一製造'CommentedSeq/Dict''列表/ dict':'數據= CommentedMap([ ( '一個',1), ( 'B',2), ('c',CommentedSeq(['x','y',CommentedMap([''','i'),('l',42),('m','∞')])])) ) ])'。元組列表對於保持舊版本Python中的排序是必要的 – Anthon

+0

有趣的是,我已經完成了大部分已經構建的實現。應該很容易添加到我現有的過濾系統中。 –

+0

下一次你遇到困難時,在你的問題中包括你有什麼代碼,然後更準確地回答(並且只能)你需要的東西。 – Anthon