目前发现这样一个问题:
自定义一个 dict 子类,并且实现自定义 __bool__ 方法后 json.dumps() 会产生和预期不符的结果
话不多说,上代码
import json
class InnerDict(dict):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def __bool__(self):
# 原始这里的逻辑是只要字典为空才返回 False,非空都返回 True
# 但是如果改掉比如这里所有都返回 False
return False
dct = InnerDict()
dct["hello] = "world"
print(dct) # 到这里都没有问题
json.dumps(dct, ensure_ascii=False, indent=4) # 但是这里,dumps 的结果就是 {}
原因分析:
在 json 库 encoder.py 文件中 _make_iterencode 方法内有个闭包的方法 _iterencode_dict
在这方法中第一件事去判断 dct 是否为空,用了
if not dct:
yield '{}'
return
截图在这里 https://www.v2ex.com/i/5Xjw6YFt.jpeg
但是问题就在这里,这里会调用 __bool__ 判断,但是 __bool__ 的逻辑已经被改了,所以在上面的代码里这里一直为 {}
而且追踪了 _iterencode_dict 方法,发现三处调用处均判断了 dct 对象为 dict
这里的 if not dct 仅仅做了判断 dct 是否为空 dict
目前就是这么个情况,不知道这算不算一个 bug