2012-12-22 55 views
6

我爲計算機使用YAML併爲模擬器使用了可編輯和可讀的輸入格式。對於人類的可讀性而言,輸入的某些部分主要適合於阻擋風格,而流動風格更適合其他風格。指定PyYAML轉儲部分的樣式

PyYAML的默認值是在任何有嵌套的地圖或序列的地方使用塊樣式,在其他地方使用流式樣。 * default_flow_style *允許您選擇全流式或全部流式。

但我想輸出更多形式的文件

bonds: 
- { strength: 2.0 } 
- ... 
tiles: 
- { color: red, edges: [1, 0, 0, 1], stoic: 0.1} 
- ... 
args: 
    block: 2 
    Gse: 9.4 

可以看出,這並不遵循一個風格一致的模式貫穿始終,這取決於文件的一部分,而不是改變。本質上,我希望能夠指定某些塊樣式序列中的所有值都是流式樣。有什麼方法可以對傾銷進行這種精細的控制嗎?能夠以特定的順序轉儲頂層映射,而不需要該順序(例如,omap),以及可讀性。

回答

11

事實證明,這可以通過爲代表每個我不想遵循default_flow_style的項目的代表人員定義子類,然後將所有必需的東西轉換爲傾倒前的東西來完成。在這種情況下,這意味着我得到的東西,如:

class blockseq(dict): pass 
def blockseq_rep(dumper, data): 
    return dumper.represent_mapping(u'tag:yaml.org,2002:map', data, flow_style=False) 

class flowmap(dict): pass 
def flowmap_rep(dumper, data): 
    return dumper.represent_mapping(u'tag:yaml.org,2002:map', data, flow_style=True) 

yaml.add_representer(blockseq, blockseq_rep) 
yaml.add_representer(flowmap, flowmap_rep) 

def dump(st): 
    st['tiles'] = [ flowmap(x) for x in st['tiles'] ] 
    st['bonds'] = [ flowmap(x) for x in st['bonds'] ] 
    if 'xgrowargs' in st.keys(): st['xgrowargs'] = blockseq(st['xgrowargs']) 
    return yaml.dump(st) 

煩人,更容易使用的dumper.represent_list和dumper.represent_dict不允許指定flow_style,所以我必須指定標籤,但系統確實有效。

+0

您的評論仍然是最新的關於'dumper.represent_sequence'和'dumper.represent_dict'沒有選項flow_style嗎?請參閱http://pyyaml.org/wiki/PYYAMLDocumentation#Dumper – Hotschke

+0

其實我試着在一個序列上應用你的'flowmap':' - edges:\ n - [1,2] \ n - [2,1,[1 ,0]]'。我希望在單獨的一行上有每條邊(如'\ n'所示)。目前,它看起來像這樣:' - 邊緣:\ n - [1,2] \ n - 1 \ n - 2 \ n - [1,0]' – Hotschke

+0

是的,我的評論仍然有效; 'represent_mapping'有它,但另外兩個沒有;他們可能只是'represent_mapping'的包裝器。至於你在做什麼,流程圖不是你想要的。你有一個序列(在邊緣:),你想要有flow_style = True,而不是映射。 – cge