【发布时间】:2014-01-18 06:44:48
【问题描述】:
我正在尝试覆盖dict 在json.dumps 上的行为。例如,我可以订购钥匙。因此,我创建了一个继承 if dict 的类,并覆盖了它的一些方法。
import json
class A(dict):
def __iter__(self):
for i in range(10):
yield i
def __getitem__(self, name):
return None
print json.dumps(A())
但它不调用我的任何方法,只给我{}
有一种方法可以给我正确的行为:
import json
class A(dict):
def __init__(self):
dict.__init__(self, {None:None})
def __iter__(self):
for i in range(10):
yield i
def __getitem__(self, name):
return None
print json.dumps(A())
Wich 终于给了{"0": null, "1": null, "2": null, "3": null, "4": null, "5": null, "6": null, "7": null, "8": null, "9": null}
因此,很明显json.dumps 的C 实现以某种方式测试dict 是否为空。不幸的是,我无法弄清楚调用了哪个方法。首先,__getattribute__ 不起作用,其次我已经覆盖了 dict 定义或可能定义但没有成功的所有方法。
那么,有人可以向我解释一下 json.dumps 的 C 实现如何检查 dict 是否为空,有没有办法覆盖它(我觉得我的 __init__ 很丑)。
谢谢。
编辑:
我终于找到了这个在 C 代码中的附加位置,而且看起来不能自定义
_json.c 第 2083 行:
if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
open_dict = PyString_InternFromString("{");
close_dict = PyString_InternFromString("}");
empty_dict = PyString_InternFromString("{}");
if (open_dict == NULL || close_dict == NULL || empty_dict == NULL)
return -1;
}
if (Py_SIZE(dct) == 0)
return PyList_Append(rval, empty_dict);
所以看起来Py_SIZE 用于检查dict 是否为空。但这是一个宏(不是函数),它只返回python对象的一个属性。
object.h 第 114 行:
#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
因此,由于它不是函数,因此无法覆盖,因此无法自定义其行为。
最后,如果想要通过继承 dict 来自定义 json.dumps,则“非空 dict 技巧”是必要的(当然其他方法也可以实现)。
【问题讨论】:
-
不,不使用
__len__。
标签: python json python-2.7 dictionary