2013-04-28 29 views
10

Tôi muốn kết xuất một từ điển Python vào một tệp JSON với một định dạng tùy chỉnh cụ thể. Ví dụ, từ điển sau my_dict,JSON đổ định dạng tùy chỉnh

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

đổ với

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

trông như thế này

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

trong khi tôi thích nó trông như thế này

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

Simila rly, tôi muốn những điều sau

"location": [ 
    22, 
    -8 
    ] 

trông như thế này

"location": [22, -8] 

(có nghĩa là, giống như một phối hợp, mà nó là).

Tôi biết rằng đây là vấn đề về mỹ phẩm, nhưng điều quan trọng là tôi phải giữ nguyên định dạng này để chỉnh sửa thủ công tệp dễ dàng hơn.

Bất kỳ cách nào để thực hiện loại tùy chỉnh này? Một ví dụ giải thích sẽ là tuyệt vời (các tài liệu đã không nhận được tôi rất xa).

+1

Điều đó, BTW, không phải là JSON hợp lệ ... thậm chí có hoạt động không? – SuperSaiyan

+1

Không phải để tin tưởng vào điểm nhưng dích của bạn vẫn không hợp lệ. (tức là mỗi dict cần một khóa và giá trị: {"line1": "value1}). Bạn đã bao giờ con số này ra? Tôi không chắc chắn làm thế nào để sử dụng JSONEncoder để làm điều này. 01 –

Trả lời

2

Bạn sẽ cần tạo một lớp con của lớp json.JSONEncoder và ghi đè các phương thức cho từng loại giá trị để chúng viết định dạng bạn cần. Bạn có thể kết thúc việc triển khai lại hầu hết trong số đó, tùy thuộc vào nhu cầu định dạng của bạn.

http://docs.python.org/2/library/json.html có ví dụ để mở rộng bộ mã hóa JSONEncoder.

+1

Một ví dụ sẽ được tốt đẹp. làm thế nào để sử dụng JSONEncoder để làm điều này. –

3

Đây là thứ tôi đã tấn công cùng nhau. Không phải là rất đẹp nhưng có vẻ như nó hoạt động. Có thể bạn có thể xử lý các từ điển đơn giản theo cách tương tự.

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) 

LƯU Ý: Đó là khá nhiều không cần thiết trong mã này để được kế thừa từ JSONEncoder.

+1

Lưu ý rằng bạn có thể thay thế '" ".join ([" "cho x trong phạm vi (self.current_indent)])' với '" "* self.current_indent' ;-) – Johan

Các vấn đề liên quan