Reputation: 9943
I was trying to serialize my objects in a way that I could read them in the external form and found jsonpickle. But it turns out that it converts my dictionary keys from integers to strings.
I noticed this thread on the problem using just the JSON package but I was hoping that jsonpickle would fix the problem. Are there any known workarounds? Alternatively is there a better text-mode serialization format to use for Python?
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
>>> a={}
>>> a[11]="eleventy"
>>> a[22]="twice that"
>>> a
{11: 'eleventy', 22: 'twice that'}
>>> import jsonpickle
>>> jstring=jsonpickle.encode(a)
>>> jstring
'{"22": "twice that", "11": "eleventy"}'
>>> b=jsonpickle.decode(jstring)
>>> b
{'22': 'twice that', '11': 'eleventy'}
>>>
Update: For short term my work around is to have parallel save functions -- one to pickle and one to jsonpickle. Since my objects are complex (circular references) I can't get away with something that can't handle that. My original requirement was to have a format that I could read in a text editor so I could detect problems with the logic so as long as regular pickel is reliable (it is) than that will do me for now. Someday I might want to have some other non-Python software eat this file so I would like to find a usable solution. XML format? The Python community doesn't seem to be that interested in serializing to XML. At least I haven't found a package that works as easily as pickle/jsonpickle does.
Upvotes: 5
Views: 3561
Reputation: 866
In jsonpickle you can use the 'keys' argument to save keys without coercing them to string.
To encode, do:
jsonpickle.encode(your_object, keys=True)
and to decode:
jsonpickle.decode(the_encoded_object, keys=True)
Upvotes: 5
Reputation: 19318
This is the JSON object definition from http://json.org. So basically all keys MUST be string, so your int key will be converted to string when converting object to JSON object. Nothing else.
You don't have to use jsonpickle if all you need is string representation.
>>> a={}
>>> a[11]="eleventy"
>>> a[22]="twice that"
>>> str(a)
"{11: 'eleventy', 22: 'twice that'}"
Upvotes: 1
Reputation: 28596
You could use repr
for small things or pprint
in general:
>>> a = {i: i for i in range(20)}
>>> import pprint
>>> pprint.pprint(a)
{0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9,
10: 10,
11: 11,
12: 12,
13: 13,
14: 14,
15: 15,
16: 16,
17: 17,
18: 18,
19: 19}
You can also give pprint
a stream to write into:
with open('mydata.txt', 'w') as f:
pprint.pprint(a, f)
And you can read that back like this:
import ast
with open('mydata.txt') as f:
b = ast.literal_eval(f.read())
Upvotes: 1
Reputation: 4037
This is because the JSON format (http://json.org/) requires all keys in an object (dict keys in python) to be strings.
Though not text based, MessagePack allows integer mapping keys:
>>> import msgpack
>>> type(msgpack.unpackb(msgpack.packb({12: 23})).keys()[0])
<type 'int'>
Upvotes: 1