跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • python3 中 json 的一个 bug?
未分類
6 11 月 2020

python3 中 json 的一个 bug?

python3 中 json 的一个 bug?

資深大佬 : deplives 4

目前发现这样一个问题:

自定义一个 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

大佬有話說 (16)

  • 資深大佬 : ruanimal

    这不算 bug 吧。。

    而且你这个继承违反了里氏代换原则

  • 資深大佬 : acmore

    如果 `_iterencode_dict` 只管按自己的逻辑去判断是否为空,而不管你怎么实现 `__bool__`,这才是一个 Bug,因为实际上对 `__bool__` 的重载是无效的。

    你没有正确实现 `__bool__` 的功能,自然也得不到期待的结果。

  • 資深大佬 : zmaplex

    不算,我认为你破坏了设计上的传递性。

  • 資深大佬 : Vinty

    对象为空,所以 dump 也是空的,这很符合逻辑啊

  • 資深大佬 : ofooo

    不要弄 dict 的子类,确实有 bug,python 猫公众号前几天还讲过。

    不要弄 python 官方类的子类的魔法函数,他继承顺序有一定的不一致性

  • 資深大佬 : ofooo

    不过感觉你这个是自作自受吧。。。。人家这个逻辑没问题啊

  • 資深大佬 : xuboying

    看了半天没理解 op 觉得哪里是 bug ?是对那个 if 判断的条件有异议么? op 期望是怎样的结果。

  • 資深大佬 : cz5424

    这个问题类似于,我修改了支付宝客服端,加了个一百万,但是我买不了东西

  • 資深大佬 : Wincer

    主意思是 if not dct 应该改成 if dct is not {}?

  • 資深大佬 : SjwNo1

    那就再改 __bool__ 知道你满意为止哈哈

  • 資深大佬 : mringg

    我想说人生已经够难了,不要难为自己了,就用些基本的用法不好么

  • 資深大佬 : no1xsyzy

    dict 的 __bool__ 含义就是这个 dict 是否为空
    _iterencode_dict 说:既然你说它是空,那它就是空咯,不反驳,'{}’ 来

  • 資深大佬 : timothyqiu

    说白了就是 garbage in, garbage out

  • 資深大佬 : cnrting

    都用 python 了何苦再为难自己

  • 資深大佬 : lithbitren

    只有在算法题里写字典树的时候会继承字典,其他情况下原则上都不会继承这些基础数据结构

  • 資深大佬 : krixaar

    这是不是可以类比成后端偷偷改了接口返回值,前端崩了说是前端有 bug ?

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具