Python JSON转储自定义格式
我想将Python字典转储到具有特定自定义格式的JSON文件中。例如,以下词典Python JSON转储自定义格式,python,json,dictionary,Python,Json,Dictionary,我想将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": [
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]
而我更喜欢它看起来像这样
"text_lines": [
{
"line1"
},
{
"line2"
}
]
"text_lines":
[
{"line1"},
{"line2"}
]
"location": [22, -8]
同样,我想要以下内容
"location": [
22,
-8
]
像这样
"text_lines": [
{
"line1"
},
{
"line2"
}
]
"text_lines":
[
{"line1"},
{"line2"}
]
"location": [22, -8]
(也就是说,更像一个坐标,它是)
我知道这是一个表面上的问题,但对我来说保留这种格式很重要,以便手动编辑文件
有没有办法进行这种定制?一个解释过的例子会很好(文档没有让我走得太远)。您需要创建json.jsonecoder类的子类并重写这些方法 对于每种类型的值,它们都会编写所需的格式。您可能会重新实现 大多数,取决于您的格式需要 有一个扩展的例子
JSONECODER。这是我拼凑的东西。不是很漂亮,但似乎很管用。您可能可以用类似的方式处理简单的词典
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.items():
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)
注意:在这段代码中,从
jsonecoder
继承几乎是不必要的 我使用了Tim Ludwinski提供的示例,并根据我的喜好进行了调整:
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 "[\n" + ",\n".join(output) + "\n" + 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 "{\n" + ",\n".join(output) + "\n" + 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
class CompactJSONEncoder(json.JSONEncoder):
“”“将小列表放在单行上的JSON编码器。”“”
定义初始化(self,*args,**kwargs):
super()
self.u级别=0
def编码(自身,o):
“”“针对单行列表对JSON对象*o*进行编码。”“”
如果isinstance(o,(列表,元组)):
如果self.\u是单行列表(o):
返回“[”+“,”.join(o中el的json.dumps(el)+”]”
其他:
self.u级别+=1
输出=[self.indent_str+self.encode(el)表示el在o中]
self.u level-=1
返回“[\n”+”,\n.join(output)+“\n”+self.indent\u str+”]
elif isinstance(o,dict):
self.u级别+=1
output=[self.indent_str+f“{json.dumps(k)}:{self.encode(v)}”表示k,v在o.items()中]
self.u level-=1
返回“{\n”+”,\n.join(output)+“\n”+self.indent\u str+”}”
其他:
返回json.dumps(o)
定义是单行列表(self,o):
如果isinstance(o,(列表,元组)):
对于o中的el,不返回任何(isinstance(el,(list,tuple,dict))值)\
顺便说一句,len(o)不是一个有效的JSON。。。它是否真的起作用了?不是为了说明问题,但你的json指令仍然无效。(即每个dict都需要一个键和值:{“line1”:“value1})。你知道吗?我不知道如何使用JSONEncoder来实现这一点。举个例子就好了。不知道如何使用JSONEncoder来实现这一点。请注意,你可以用替换”。join([“”表示范围内的x(self.current\u indent)])
“*自身当前缩进
;-)如果有人想知道:这对于打印GeoJSON非常有效。我非常喜欢你的解决方案,尤其是要点中的解决方案,谢谢。