网站后台上传图片 不可用/网址域名大全
12.9.5 编码器和解码器类
除了之前介绍的便利函数,json模块还提供了一些类来完成编码和解码。直接使用这些类可以访问另外的API来定制其行为。
JSONEncoder使用一个iterable接口生成编码数据“块”,从而更容易将其写至文件或网络套接字,而不必在内存中表示完整的数据结构。
import jsonencoder = json.JSONEncoder()
data = [{'a':'A','b':(2,4),'c':3.0}]for part in encoder.iterencode(data):print('PART:',part)
输出按逻辑单元生成,而不是根据某个大小值。
运行结果:
encode()方法基本上等价于’’.join(encoder.iterencode()),只不过之前会做一些额外的错误检查。要对任意的对象编码,需要用一个实现覆盖default()方法,这个实现类似于convert_to_builtin_type()中的实现。
import json
import json_myobjclass MyEncoder(json.JSONEncoder):def default(self,obj):print('default(',repr(obj),')')# Convert objects to a dictionary of their representation.d = {'__class__':obj.__class__.__name__,'__module__':obj.__module__,}d.update(obj.__dict__)return dobj = json_myobj.MyObj('internal data')
print(obj)
print(MyEncoder().encode(obj))
输出与前一个实现的输出相同。
运行结果:
这里要解码文本,然后将字典转换为一个对象,与前面的实现相比,这需要多做一些工作,不过不算太多。
import jsonclass MyDecoder(json.JSONDecoder):def __init__(self):json.JSONDecoder.__init__(self,object_hook=self.dict_to_object,)def dict_to_object(self,d):if '__class__' in d:class_name = d.pop('__class__')module_name = d.pop('__module__')module = __import__(module_name)print('MODULE:',module.__name__)class_ = getattr(module,class_name)print('CLASS:',class_)args = {key:valuefor key,value in d.items()}print('INSTANCE ARGS:',args)inst = class_(**args)else:inst = dreturn instencoded_object = '''
[{"s":"instance value goes here",
"__module__":"json_myobj","__class__":"MyObj"}]
'''myobj_instance = MyDecoder().decode(encoded_object)
print(myobj_instance)
输出与前面的例子相同。
运行结果: