2013-04-28 83 views
10

我想用特定的自定義格式將Python字典轉儲到JSON文件中。例如,下面的解釋my_dictJSON轉儲自定義格式

'text_lines': [{"line1"}, {"line2"}] 

f.write(json.dumps(my_dict, sort_keys=True, indent=2)) 

傾倒看起來像這樣

"text_lines": [ 
    { 
     "line1" 
    }, 
    { 
     "line2" 
    } 
    ] 

,而我更喜歡它看起來像這樣

"text_lines": 
    [ 
    {"line1"}, 
    {"line2"} 
    ] 

Simila RLY,我想下面的

"location": [ 
    22, 
    -8 
    ] 

看起來像這樣

"location": [22, -8] 

(即,更像是一個座標,它是)。

我知道這是一個整容問題,但保留此格式以便於手動編輯文件很重要。

做這種定製的任何方式?一個解釋的例子會很好(文檔沒有讓我很遠)。

+1

那,順便說一句,不是一個有效的JSON ......它甚至工作? – SuperSaiyan 2013-04-28 15:56:01

+1

不是要點,但你的JSON字典仍然無效。 (即每個字典需要一個鍵和值:{「line1」:「value1})。你有沒有想過這個?我不知道如何使用JSONEncoder來做到這一點。 – 2014-10-22 15:11:16

回答

2

您需要爲每種類型的值創建json.JSONEncoder類的子類並覆蓋方法 ,以便他們編寫所需的格式。您可能最終會重新實施 ,這取決於您的格式需求。

http://docs.python.org/2/library/json.html有一個擴展 JSONEncoder的例子。

+1

一個例子會很好。 – 2014-10-22 15:11:37

3

這是我一起入侵的東西。不是很漂亮,但它似乎工作。你可以用類似的方式處理簡單的字典。

class MyJSONEncoder(json.JSONEncoder): 
    def __init__(self, *args, **kwargs): 
     super(MyJSONEncoder, self).__init__(*args, **kwargs) 
     self.current_indent = 0 
     self.current_indent_str = "" 

    def encode(self, o): 
     #Special Processing for lists 
     if isinstance(o, (list, tuple)): 
      primitives_only = True 
      for item in o: 
       if isinstance(item, (list, tuple, dict)): 
        primitives_only = False 
        break 
      output = [] 
      if primitives_only: 
       for item in o: 
        output.append(json.dumps(item)) 
       return "[ " + ", ".join(output) + " ]" 
      else: 
       self.current_indent += self.indent 
       self.current_indent_str = "".join([ " " for x in range(self.current_indent) ]) 
       for item in o: 
        output.append(self.current_indent_str + self.encode(item)) 
       self.current_indent -= self.indent 
       self.current_indent_str = "".join([ " " for x in range(self.current_indent) ]) 
       return "[\n" + ",\n".join(output) + "\n" + self.current_indent_str + "]" 
     elif isinstance(o, dict): 
      output = [] 
      self.current_indent += self.indent 
      self.current_indent_str = "".join([ " " for x in range(self.current_indent) ]) 
      for key, value in o.iteritems(): 
       output.append(self.current_indent_str + json.dumps(key) + ": " + self.encode(value)) 
      self.current_indent -= self.indent 
      self.current_indent_str = "".join([ " " for x in range(self.current_indent) ]) 
      return "{\n" + ",\n".join(output) + "\n" + self.current_indent_str + "}" 
     else: 
      return json.dumps(o) 

注意:這段代碼幾乎不需要從JSONEncoder繼承。

+1

請注意,您可以使用'「」* self.current_indent' ;-)來代替'「」.join([「」for x in range(self.current_indent)])''' – Johan 2017-01-09 13:01:14