Saa*_*mer 16 python json dictionary
我想将Python字典转储到具有特定自定义格式的JSON文件中.例如,以下字典my_dict
,
'text_lines': [{"line1"}, {"line2"}]
Run Code Online (Sandbox Code Playgroud)
甩了
f.write(json.dumps(my_dict, sort_keys=True, indent=2))
Run Code Online (Sandbox Code Playgroud)
看起来像这样
"text_lines": [
{
"line1"
},
{
"line2"
}
]
Run Code Online (Sandbox Code Playgroud)
虽然我更喜欢它看起来像这样
"text_lines":
[
{"line1"},
{"line2"}
]
Run Code Online (Sandbox Code Playgroud)
同样,我想要以下内容
"location": [
22,
-8
]
Run Code Online (Sandbox Code Playgroud)
看起来像这样
"location": [22, -8]
Run Code Online (Sandbox Code Playgroud)
(也就是说,它更像是一个坐标).
我知道这是一个美容问题,但对我来说保留这种格式以便于手动编辑文件非常重要.
有没有办法做这种定制?一个解释的例子会很棒(文档并没有让我走得太远).
我使用了 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
def iterencode(self, o, **kwargs):
"""Required to also work with `json.dump`."""
return self.encode(o)
Run Code Online (Sandbox Code Playgroud)
这是我一起入侵的东西.不是很漂亮,但它似乎工作.您可以以类似的方式处理简单的词典.
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)
Run Code Online (Sandbox Code Playgroud)
注意:此代码中几乎没有必要继承JSONEncoder
.
小智 3
您将需要创建 json.JSONEncoder 类的子类并重写每种值类型的方法,以便它们编写您需要的格式。您最终可能会重新实现其中的大多数,具体取决于您的格式化需求。
http://docs.python.org/2/library/json.html有一个扩展 JSONEncoder 的示例。
归档时间: |
|
查看次数: |
11980 次 |
最近记录: |