Pythonオブジェクトをjsonモジュールでjsonにシリアライズ
前の記事で書いたjsonシリアライザの仕組みを、自作のパーサではなくjsonモジュールで実装した。32行で実装できた。お手軽。ユーザ定義型のシリアライズの方法は同じで、__encode_json__で永続化したいオブジェクトを返して、__decode_json__クラスメソッドで復元したクラスを返す。あとobjectオブジェクトを継承する。
# coding: utf-8 import json def object_hooker_factory(clslist): clsnamelist = [cls.__name__ for cls in clslist] def object_hook(dic): if "__class__" in dic and dic["__class__"] in clsnamelist: cls = clslist[clsnamelist.index(dic["__class__"])] return cls.__decode_json__(dic["__value__"]) return dic return object_hook class Serializer(json.JSONEncoder): def default(self, obj): if not type(obj) in [int, float, str, unicode, list, dict]: value = eval(self.encode(obj.__encode_json__())) name = obj.__class__.__name__ return {"__class__": name, "__value__": value} return json.JSONEncoder.default(self, obj) def loads(s, clslist=[]): object_hook = object_hooker_factory(clslist) return json.loads(s, object_hook=object_hook) def load(fp, clslist=[]): return loads(fp.read(), clslist) def dumps(obj): return json.dumps(obj, cls=Serializer) def dump(fp, obj): fp.write(dumps(obj)) """ # sample class Point(object): def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return "(%.2f, %.2f)" % (self.x, self.y) def __encode_json__(self): return [self.x, self.y] @classmethod def __decode_json__(cls, lst): return cls(*lst) class Rectangle(object): def __init__(self, p, q): self.p = p self.q = q def __repr__(self): return "<Point %s %s>" % (self.p, self.q) def __encode_json__(self): return [self.p, self.q] @classmethod def __decode_json__(cls, lst): return cls(*lst) p = Point(0, 1) q = Point(5, 6) r = Rectangle(p, q) print dumps(p) print dumps(r) print loads(dumps(p), [Point,Rectangle]) print loads(dumps(r), [Point,Rectangle]) """
シリアライズする際に何度もevalってるのを短くできると速くなると思う。