python: behavior of json.dumps on dict
我想超越?
1 2 3 4 5 6 7 8 9 10 | 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()) |
但它没有调用我的任何方法,只给了我
有一种方法可以让我了解这种行为:
1 2 3 4 5 6 7 8 9 10 11 12 | 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()) |
威奇最后给了埃多克斯1〔4〕。
因此,很明显,
所以,有人能给我解释一下,c实现
谢谢您。
编辑:
我终于在C代码中找到了这个附加的地方,它看起来不可定制。
_ json.c第2083行:
1 2 3 4 5 6 7 8 9 | 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); |
因此,似乎使用
对象H第114行:
1 2 3 | #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子类?
1 2 3 4 5 6 | class OrderedDictJSONEncoder(json.JSONEncoder): def default(self, obj): if hasattr(obj, 'keys'): return {} # replace your unordered dict with an OrderedDict from collections else: return super(OrderedDictJSONEncoder, self).default(obj) |
像这样使用它:
1 | json.dumps(my_dict_to_encode, cls=OrderedDictJSONEncoder) |
这似乎是将无序的python dict转换为有序的json对象的正确地方。
我不知道编码器具体做什么,但它不是用C编写的,json包的python源代码在这里:http://hg.python.org/cpython/file/2A872126f4a1/lib/json
另外,如果您只想订购这些商品,还有
1 | json.dumps(A(), sort_keys=True) |
另请参阅此问题("如何完全重写dict?")它的第一个答案,解释了在大多数情况下应该对collections.mutablemapping进行子类化。
或者像Aychedee提到的那样,只提供一个子类编码器。