Storing instances using jsonpickle

MRAB python at mrabarnett.plus.com
Thu Sep 4 01:39:07 CEST 2014


On 2014-09-03 23:30, Josh English wrote:
> On Wednesday, September 3, 2014 1:53:23 PM UTC-7, Ned Batchelder
> wrote:
>
>> Pickle (and it looks like jsonpickle) does not invoke the class'
>> __init__ method when it reconstitutes objects.  Your new __init__
>> is not being run, so new attributes it defines are not being
>> created.
>>
>> This is one of the reasons that people avoid pickle: being
>> completely implicit is very handy, but also fragile.
>>
>
> I seem to remember having this exact same frustration when I used
> pickle and shelve 15 years ago. I had hoped to have another way
> around this. I spent over a decade trying to make an XML-based
> database work, in part because of this limitation.
>
> Some days I get so frustrated I think the only data structure I
> should ever use is a dictionary.
>
> I suppose to make this sort of thing work, I should look at creating
> custom json encoders and decoders.
>
I occasionally think about a superset of JSON, called, say, "pyson" ...
ah, name already taken! :-(

In summary, it would be something like this:

JSON supports int, float, string, None (as 'null'), list and dict (the 
key must be string).

It would add tuples, delimited by (...), which are not used otherwise 
(no expressions):

     () => ()
     (0, ) => (0)
     (0, 1) => (0, 1)

The key of a dict could also be int, float, or tuple.

It could support other classes, and could handle named arguments.

For example, sets:

To encode {0, 1, 2):

     Look in encoder dict for encoder function with class's name ('set') 
and call it, passing object.

     Encoder returns positional and keyword arguments: [0, 1, 2] and {}.

     Output name, followed by encoded arguments in parentheses.

     Encoder for set:

     def encode_set(obj):
         return list(obj), {}

To decode 'set(0, 1, 2)':

     Parse name: 'set'.

     Parse contents of parentheses: [0, 1, 2] and {}.

     Look in decoder dict for decoder function with given name ('set') 
and call it, passing arguments.

     Result would be {0, 1, 2}.

     Decoder for set:

     def decode_set(*args):
         return set(args)

pyson.dumps({0, 1, 2}, decoders={'set': decode_set}) would return 
'set(0, 1, 2)'.

pyson.loads('set(0, 1, 2)', encoders={'set': encode_set}) would return 
{0, 1, 2}.



More information about the Python-list mailing list