首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于json.dump和json.dumps,json编码器的不同结果

对于json.dump和json.dumps,json编码器的不同结果
EN

Stack Overflow用户
提问于 2018-10-22 23:49:29
回答 2查看 3.1K关注 0票数 3

我用这种格式的字符串,

代码语言:javascript
复制
d = {'details': {'hawk_branch': {'tandem': ['4210bnd72']}, 'uclif_branch': {'tandem': ['e2nc712nma89', '23s24212', '12338cm82']}}}

我想把它写成这种格式的文件,将列表转换成字典,并为列表中的每个值添加单词value作为键,因此{'tandem': ['4210bnd72']}应该成为

代码语言:javascript
复制
  "tandem": {
    "value": "4210bnd72"
  }

这是预期的输出文件,

代码语言:javascript
复制
{
  "details": {

    "hawk_branch": {
      "tandem": {
        "value": "4210bnd72"
      }
    },
    "uclif_branch": {
      "tandem": {
        "value": "e2nc712nma89",
        "value": "23s24212",
        "value": "12338cm82",
      }
    }
    }
}

我问了一个问题,here,有人回答了使用json.JSONEncoder

代码语言:javascript
复制
class restore_value(json.JSONEncoder):
    def encode(self, o):
        if isinstance(o, dict):
            return '{%s}' % ', '.join(': '.join((json.encoder.py_encode_basestring(k), self.encode(v))) for k, v in o.items())
        if isinstance(o, list):
            return '{%s}' % ', '.join('"value": %s' % self.encode(v) for v in o)
        return super().encode(o)

使用上面的编码器,如果输入

代码语言:javascript
复制
d = {'details': {'hawk_branch': {'tandem': ['4210bnd72']}, 'uclif_branch': {'tandem': ['e2nc712nma89', '23s24212', '12338cm82']}}}

输出会变成,

代码语言:javascript
复制
print(json.dumps(d, cls=restore_value))
{"details": {"hawk_branch": {"tandem": {"value": "4210bnd72"}}, "uclif_branch": {"tandem": {"value": "e2nc712nma89", "value": "23s24212", "value": "12338cm82"}}}}

这正是我想要的,但现在我想把它写到一个文件中。

代码语言:javascript
复制
with open("a.json", "w") as f:
    json.dump(d, f, cls=restore_value)

但它的编写方式与json.dumps的输出不同。

预期输出,

代码语言:javascript
复制
{"details": {"hawk_branch": {"tandem": {"value": "4210bnd72"}}, "uclif_branch": {"tandem": {"value": "e2nc712nma89", "value": "23s24212", "value": "12338cm82"}}}}

我得到的输出,

代码语言:javascript
复制
{"details": {"hawk_branch": {"tandem": ["4210bnd72"]}, "uclif_branch": {"tandem": ["e2nc712nma89", "23s24212", "12338cm82"]}}}

有人能告诉我,为什么它的写入一个文件不同,即使我使用的编码器?

再生,

使用python 3复制并运行

代码语言:javascript
复制
import json


class restore_value(json.JSONEncoder):
    def encode(self, o):
        if isinstance(o, dict):
            return '{%s}' % ', '.join(': '.join((json.encoder.py_encode_basestring(k), self.encode(v))) for k, v in o.items())
        if isinstance(o, list):
            return '{%s}' % ', '.join('"value": %s' % self.encode(v) for v in o)
        return super().encode(o)

d = {'details': {'hawk_branch': {'tandem': ['4210bnd72']}, 'uclif_branch': {'tandem': ['e2nc712nma89', '23s24212', '12338cm82']}}}
print(json.dumps(d, cls=restore_value))


with open("a.json", "w") as f:
  json.dump(d, f, cls=restore_value)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-23 00:05:28

原因是:

如果您在github:json.__init__.py中查看CPython/Lib/json中的CPython/Lib/json源代码:.py

您会发现json.dump实际上使用:

代码语言:javascript
复制
if (not skipkeys and ensure_ascii and
    check_circular and allow_nan and
    cls is None and indent is None and separators is None and
    default is None and not sort_keys and not kw):
    iterable = _default_encoder.iterencode(obj)
else:
    if cls is None:
        cls = JSONEncoder
    iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
        check_circular=check_circular, allow_nan=allow_nan, indent=indent,
        separators=separators,
        default=default, sort_keys=sort_keys, **kw).iterencode(obj)
# could accelerate with writelines in some versions of Python, at
# a debuggability cost
for chunk in iterable:
    fp.write(chunk)

因此,您想要override的函数应该是json.JSONEncoder.iterencode而不是encode

票数 6
EN

Stack Overflow用户

发布于 2018-10-23 00:19:44

json.dumpscls一起调用JSON对象上的encode方法,该方法将返回字符串表示形式。另一方面,json.dump将调用尚未实现的default方法。来自json.dump文档:

若要使用自定义JSONEncoder子类(例如,重写默认()方法以序列化其他类型的子类),请使用cls指定它;否则将使用JSONEncoder。

因此,json.dump使用的是默认的default方法,它不影响原始对象并写入该方法。

以您想要的方式编写文件的最简单方法是

代码语言:javascript
复制
with open("a.json", "w") as f:
    f.write(json.dumps(d, cls=restore_value))
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52939176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档