how to reinitialize the class instance decoded from jsonpickle

98 views Asked by At

Lets say I have this class

class LineItem:
   def __init__(self):
        self.var1 = 1

When I encode this json with JSON pickle it will save all the attributes and class definition. And after encoding, lets say I change the class to following.

class LineItem:
   def __init__(self):
        self.var1 = 1
        self.var2 = 2

Now after changing the line item, if I decode the existing json with JSON pickle. The newly decoded class instance of LineItem will not have attribute var2. So if I try to access it, it will throw an error.

In my opinion, there should be an option to reinitialize the class instance.

1

There are 1 answers

1
aaron On

Implement the __setstate__() method:

class LineItem:
    def __init__(self):
        self.var1 = 1
        self.var2 = 2

    def __setstate__(self, state: dict):
        state.setdefault('var2', 2)
        self.__dict__.update(state)

existing pickled JSONs won't work. By existing, I mean, JSONs that were produced before implementing a __setstate__ and __getstate__

You can override Unpickler _restore_object_instance_variables to always call __setstate__:

import jsonpickle
from jsonpickle import tags


class Unpickler(jsonpickle.Unpickler):

    def _restore_object_instance_variables(self, obj, instance):
        if hasattr(instance, '__setstate__'):
            obj.setdefault(tags.STATE, {})
        return super()._restore_object_instance_variables(obj, instance)

Usage:

s = '{"py/object": "__main__.LineItem", "var1": 1}'
context = Unpickler()
print(jsonpickle.decode(s, context=context).var2)