JSON удаляет настраиваемое форматирование

Я хочу сбросить словарь Python в файл JSON с определенным пользовательским форматом. Например, следующий словарь my_dict,

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

сбрасывается с помощью

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

выглядит следующим образом

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

в то время как я предпочитаю, чтобы он выглядел как

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

Аналогично, я хочу следующее

  "location": [
    22, 
    -8
  ]

чтобы выглядеть так

  "location": [22, -8]

(то есть больше похож на координату).

Я знаю, что это косметическая проблема, но мне важно сохранить это форматирование для упрощения редактирования файла вручную.

Любой способ сделать такую ​​настройку? Объясненный пример будет большим (документы не заставили меня очень далеко).

Ответ 1

Здесь что-то, что я взломал. Не очень красиво, но, похоже, работает. Вы, вероятно, могли бы обрабатывать простые словари аналогичным образом.

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.

Ответ 2

Вам нужно будет создать подкласс класса json.JSONEncoder и переопределить методы для каждого типа значения, чтобы они записывали нужный формат. Вы можете завершить повторное внедрение большинство из них, в зависимости от ваших потребностей в форматировании.

http://docs.python.org/2/library/json.html имеет пример расширения JSONEncoder.