python simplejson decoding

A

Arthur Mc Coy

Hi all,



I'm trying an example (in attached file, I mean the bottom of this
message).

First, I create a list of 3 objects. Then I do:


PutJSONObjects(objects)
objects = GetJSONObjects()
PutJSONObjects(objects, "objects2.json")


1) PutJSONObjects(objects) method creates objects.json file (by
default). It works fine.
2) Then objects = GetJSONObjects() method get the file contents and
return.

3) Finally the script fails on the third method
PutJSONObjects(objects, "objects2.json")
saying: AttributeError: 'dict' object has no attribute '__dict__'


That is true, because objects returned by GetJSONObjects() is not a
list of objects, but simple string....

So here is the question, please, how should I DECODE .json file into
list of python objects so that I will be able to put the copy of these
objects into a new file called objects2.json ?

simplejson docs are hard to follow - without examples.



Please, help me. Be happy!

Arthur

--------

# Python-JSON method for caching my objects.

import simplejson as json
import os.path
from datetime import datetime


def GetJSONObjects():

# determine the json data file path
filename = "objects.json"
filepath = "/home/docmccoy/Documents/" + filename
if os.path.isfile(filepath):
filename = filepath
f = open(filename, 'r')
objects = json.load( f )
print objects
else:
objects = list()

return objects


def PutJSONObjects(objects, filename = "objects.json"):

# determine the json data file path
filepath = "/home/docmccoy/Documents/" + filename
if os.path.isfile(filepath):
filename = filepath

f = open(filename, 'w')
json.dump([o.__dict__ for o in objects], f, indent = 4 * ' ' )


class MyObject:
def __init__(self, ID, url, category, osfamily, createDate):
self.id = ID
self.url = url
self.category = category
self.osfamily = osfamily
self.createDate = createDate


o1 = MyObject(1, "http://google.com", "search", "linux",
unicode(datetime.now()))
o2 = MyObject(2, "http://localhost", "mycomp", None,
unicode(datetime.now()))
o3 = MyObject(3, "http://milan.com", "football", "windows",
unicode(datetime.now()))

objects = list()
objects.append(o1)
objects.append(o2)
objects.append(o3)

PutJSONObjects(objects)
objects = GetJSONObjects()
PutJSONObjects(objects, "objects2.json")
 
P

Peter Otten

Arthur said:
Hi all,



I'm trying an example (in attached file, I mean the bottom of this
message).

First, I create a list of 3 objects. Then I do:


PutJSONObjects(objects)
objects = GetJSONObjects()
PutJSONObjects(objects, "objects2.json")


1) PutJSONObjects(objects) method creates objects.json file (by
default). It works fine.
2) Then objects = GetJSONObjects() method get the file contents and
return.

3) Finally the script fails on the third method
PutJSONObjects(objects, "objects2.json")
saying: AttributeError: 'dict' object has no attribute '__dict__'


That is true, because objects returned by GetJSONObjects() is not a
list of objects, but simple string....

So here is the question, please, how should I DECODE .json file into
list of python objects so that I will be able to put the copy of these
objects into a new file called objects2.json ?

simplejson docs are hard to follow - without examples.

I suggest that you use json instead which is part of the standard library
since Python 2.6. The documentation is here:

http://docs.python.org/library/json.html

If you know that there are only MyObject instances you need a function to
construct such a MyObject instance from a dictionary. You can then recreate
the objects with

objects = [object_from_dict(d) for d in json.load(f)]

or, if all dictionaries correspond to MyObject instances

objects = json.load(f, object_hook=object_from_dict)

A general implementation for old-style objects (objects that don't derive
from object) is a bit messy:

# idea copied from pickle.py
class Empty:
pass

def object_from_dict(d):
obj = Empty()
obj.__class__ = MyObject
obj.__dict__.update((str(k), v) for k, v in d.iteritems()) # *
return obj

If you are willing to make MyClass a newstyle class with

class MyObject(object):
# ...

the function can be simplified to

def object_from_dict(d):
obj = object.__new__(MyObject)
obj.__dict__.update((str(k), v) for k, v in d.iteritems()) # *
return obj

(*) I don't know if unicode attribute names can do any harm,
obj.__dict__.update(d) might work as well.
 
A

Arthur Mc Coy

Hi Peter,


I implemented my decoder using your approach. Very positive.

But that is for simple objects. My objects have nested lists. For
example MyObject has property (member) called benchmarks, which is the
list of defined benchmarks. I'm not sure if obj.__dict__.update will
help me to copy nested information. I will see later. Now, when the
testing environment is ready, I go for real world application.


Thank you!

Kostia

Arthur said:
I'm trying an example (in attached file, I mean the bottom of this
message).
First, I create a list of 3 objects. Then I do:
PutJSONObjects(objects)
objects = GetJSONObjects()
PutJSONObjects(objects, "objects2.json")
1) PutJSONObjects(objects) method creates objects.json file (by
default). It works fine.
2) Then objects = GetJSONObjects() method get the file contents and
return.
3) Finally the script fails on the third method
PutJSONObjects(objects, "objects2.json")
saying: AttributeError: 'dict' object has no attribute '__dict__'
That is true, because objects returned by GetJSONObjects() is not a
list of objects, but simple string....
So here is the question, please, how should I DECODE .json file into
list of python objects so that I will be able to put the copy of these
objects into a new file called objects2.json ?
simplejson docs are hard to follow - without examples.

I suggest that you use json instead which is part of the standard library
since Python 2.6. The documentation is here:

http://docs.python.org/library/json.html

If you know that there are only MyObject instances you need a function to
construct such a MyObject instance from a dictionary. You can then recreate
the objects with

objects = [object_from_dict(d) for d in json.load(f)]

or, if all dictionaries correspond to MyObject instances

objects = json.load(f, object_hook=object_from_dict)

A general implementation for old-style objects (objects that don't derive
from object) is a bit messy:

# idea copied from pickle.py
class Empty:
    pass

def object_from_dict(d):
    obj = Empty()
    obj.__class__ = MyObject
    obj.__dict__.update((str(k), v) for k, v in d.iteritems()) # *
    return obj

If you are willing to make MyClass a newstyle class with

class MyObject(object):
    # ...

the function can be simplified to

def object_from_dict(d):
    obj = object.__new__(MyObject)
    obj.__dict__.update((str(k), v) for k, v in d.iteritems()) # *
    return obj

(*) I don't know if unicode attribute names can do any harm,
obj.__dict__.update(d) might work as well.
 
A

Arthur Mc Coy

Good day people,


So I have python file which can handle json data to put and get back
it from a file say objects.json. Great.

Now I want to run this code from within C++ application. I used swig
to wrap the C++ class, which wants to call python code. It works fine,
because when I import native python modules like simplejson or os.path
the operation is successfull.

But how to import my custom python code (not native builtin modules) ?
There are following ways:
- import as python module
- call python file and its functions

I prefer second way because I do not know how to define my custom
module.

If you know some examples, let me know please. Yes, I'm googling and
reading off docs, but have not yet understood them.


Arthur
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,538
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top