我很难让Python的jsonpickle 0.4.0“递归”到包含自定义对象的自定义对象中下面的示例代码显示了我的问题。

import jsonpickle
import jsonpickle.handlers

class Ball(object):
    def __init__(self, color):
        self.color = color

class Box(object):
    def __init__(self, *args):
        self.contents = args

class BallHandler(jsonpickle.handlers.BaseHandler):
    def flatten(self, obj, data):
        data['color'] = obj.color
        return data

class BoxHandler(jsonpickle.handlers.BaseHandler):
    def flatten(self, obj, data):
        data['contents'] = obj.contents
        return data

jsonpickle.handlers.registry.register(Ball, BallHandler)
jsonpickle.handlers.registry.register(Box, BoxHandler)

# works OK -- correctly prints: {"color": "white"}
white_ball = Ball('white')
print jsonpickle.encode(white_ball, unpicklable=False)

# works OK -- correctly prints: [{"color": "white"}, {"color": "green"}]
green_ball = Ball('green')
balls = [white_ball, green_ball]
print jsonpickle.encode(balls, unpicklable=False)

# works OK -- correctly prints: {"contents": [1, 2, 3, 4]}
box_1 = Box(1, 2, 3, 4)
print jsonpickle.encode(box_1, unpicklable=False)

# dies with "Ball object is not JSON serializable"
box_2 = Box(white_ball, green_ball)
print jsonpickle.encode(box_2, unpicklable=False)

球有“颜色”,盒子有“内容物”。如果我有一个[本地]球数组,那么jsonpickle就可以工作。如果我有一盒[native]int,那么jsonpickle就可以了。
但如果我有一盒球,jsonpickle的炸弹。
从stacktrace中,我预感到编码器将离开"Ball object is not JSON serializable"并转到其他JSON库那显然不知道我已经注册了棒球手。
我该怎么解决?
顺便说一下,我的示例没有明确使用django的任何部分,但是我需要在django应用程序中使用这个。
提前感谢您的意见!

最佳答案

我想你可以回拨到腌制上下文继续腌制。

class BoxHandler(jsonpickle.handlers.BaseHandler):
def flatten(self, obj, data):
    return [self.context.flatten(x,reset=False) for x in obj.contents]

这似乎类似于pickler.py:44中内置的list_recurse()函数如何处理这种情况,因为flatten()只调用self._flatten(在可选地重置状态变量之后)。
def _list_recurse(self, obj): return [self._flatten(v) for v in obj]
我现在只是在测试这个,深度似乎保持在预期的水平。

10-07 13:38