为啥我的自定义 JSONEncoder.default() 忽略布尔值?
Posted
技术标签:
【中文标题】为啥我的自定义 JSONEncoder.default() 忽略布尔值?【英文标题】:Why is my custom JSONEncoder.default() ignoring booleans?为什么我的自定义 JSONEncoder.default() 忽略布尔值? 【发布时间】:2018-02-22 13:49:33 【问题描述】:我想将字典转换为 JSON 字符串,其中布尔值 True
转换为数字 1
,布尔值 False
值转换为数字 0
。我正在使用JSONEncoder
子类,但它似乎忽略了布尔值...
import json
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, bool):
return 1 if obj else 0
return super().default(obj)
data = 'key-a' : 'a', 'key-true' : True, 'key-false' : False
jsondata = json.dumps(data, cls=MyEncoder)
print(jsondata)
我希望这是结果:
"key-true": 1, "key-a": "a", "key-false": 0
但是,这就是我得到的:
"key-true": true, "key-a": "a", "key-false": false
我知道我可以在将数据传递给json.dumps
之前以编程方式修改数据,但是有什么方法可以通过JSONEncoder
子类获得我想要的结果?
【问题讨论】:
【参考方案1】:JSONEncoder
子类的default()
方法仅在编码器遇到一个它不知道如何序列化的对象时才被调用。
很遗憾,官方documentation 并没有说得很清楚。提到了,但在类构造函数的“关键字参数”部分中,而不是在方法的文档中:
如果指定,default 应该是一个函数,该函数会为无法序列化的对象调用。它应该返回对象的 JSON 可编码版本或引发
TypeError
。如果未指定,则会引发TypeError
。
这种行为很容易验证:
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, bool):
print('got bool')
return 1 if obj else 0
if isinstance(obj, Foo):
print('got Foo')
return '__Foo__': id(obj)
print('got unknown')
return super().default(obj)
>>> class Foo: pass
...
>>> s = json.dumps('a': False, 'b': True, 'c': Foo(), cls=MyEncoder)
got Foo
>>> s
'"a": false, "c": "__Foo__": 140636444256856, "b": true'
JSONEncoder
并非旨在轻松地允许覆盖它已经知道如何序列化的对象的序列化(这是一件好事:像 JSON 这样的标准的全部意义在于它们是,嗯,标准) ...因此,如果您真的想将布尔值编码为整数,那么最简单的方法可能是按照您的问题中的建议预处理数据。
【讨论】:
以上是关于为啥我的自定义 JSONEncoder.default() 忽略布尔值?的主要内容,如果未能解决你的问题,请参考以下文章