2013-04-28 55 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