JSON 转储自定义格式 [英] JSON dumps custom formatting

查看:40
本文介绍了JSON 转储自定义格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 Python 字典转储到具有特定自定义格式的 JSON 文件中.例如下面的字典my_dict,

I'd like to dump a Python dictionary into a JSON file with a particular custom format. For example, the following dictionary my_dict,

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

倾倒了

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

看起来像这样

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

虽然我更喜欢它看起来像这样

while I prefer that it looks like this

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

同样,我想要以下

  "location": [
    22, 
    -8
  ]

看起来像这样

  "location": [22, -8]

(也就是说,更像是一个坐标,它是).

(that is, more like a coordinate, which it is).

我知道这是一个表面问题,但保留这种格式以便于手动编辑文件对我来说很重要.

I know that this is a cosmetic issue, but it's important to me to preserve this formatting for easier hand editing of the file.

有什么方法可以进行这种定制?一个解释的例子会很棒(文档并没有让我走得很远).

Any way of doing this kind of customisation? An explained example would be great (the docs did not get me very far).

推荐答案

我使用了 Tim Ludwinski 提供的示例并根据我的喜好对其进行了调整:

I have used the example provided by Tim Ludwinski and adapted it to my preference:

class CompactJSONEncoder(json.JSONEncoder):
    """A JSON Encoder that puts small lists on single lines."""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.indentation_level = 0

    def encode(self, o):
        """Encode JSON object *o* with respect to single line lists."""

        if isinstance(o, (list, tuple)):
            if self._is_single_line_list(o):
                return "[" + ", ".join(json.dumps(el) for el in o) + "]"
            else:
                self.indentation_level += 1
                output = [self.indent_str + self.encode(el) for el in o]
                self.indentation_level -= 1
                return "[
" + ",
".join(output) + "
" + self.indent_str + "]"

        elif isinstance(o, dict):
            self.indentation_level += 1
            output = [self.indent_str + f"{json.dumps(k)}: {self.encode(v)}" for k, v in o.items()]
            self.indentation_level -= 1
            return "{
" + ",
".join(output) + "
" + self.indent_str + "}"

        else:
            return json.dumps(o)

    def _is_single_line_list(self, o):
        if isinstance(o, (list, tuple)):
            return not any(isinstance(el, (list, tuple, dict)) for el in o)
                   and len(o) <= 2
                   and len(str(o)) - 2 <= 60

    @property
    def indent_str(self) -> str:
        return " " * self.indentation_level * self.indent
    
    def iterencode(self, o, **kwargs):
        """Required to also work with `json.dump`."""
        return self.encode(o)

另请参阅我正在使用的版本.

这篇关于JSON 转储自定义格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆