3

got a question regarding serializing classes that I've defined. I have some classes like

class Foo:
     def __init__(self, x, y):
          self.x = x, self.y = y

     def toDict(self):
          return dict(Foo = dict(x = self.x, y = self.y))

then a class that can contain multiple Foos, such as:

class Bar:
     def __init__(self):
          self.foos = [Foo(a, b), Foo(1, 2)]

While that's a gross oversimplification of the real structure (it gets much, much more nested than that), that's a pretty decent overview. The actual data for this is coming from a pseudo-XML file without any actual structure, so I wrote a parser according to the spec given to me, so I now have all the data in a series of classes I've defined, with actual structure.

What I'm wanting to do is take this data I have and spit it out into JSON, but I really don't see a good way (I'm new to Python, this is my first real project with it).

I've defined a method in Foo, toDict(), that creates a dictionary out of the information, but that obviously isn't going to work out like I hope when I try to serialize Bar, with the multiple Foos.

Does anyone have a great way of doing this? This has been a pretty much non-stop learning/codefest the past few days and I'm out of ideas for this, which is the last part of the project. I know about the JSON module for Python, but that doesn't help me with this particular problem of getting my data into a dictionary (or something similar) that I can pass to json.dump().

Let me know if I can clarify in any way.

Thanks, T.J.

3 Answers 3

5

Several comments. First:

  • xml.dom.minidom is a built-in Python DOM implementation. Obviously if the file isn't actually XML you won't be able to use it's builtin parsing functions, but it looks like you're building a tree-like structure out of the file anyway, in which case you might as well use a minidom.

OK, henceforth I'll assume that you have a good reason for writing your own tree-style structure instead of using the builtins.

  • Are you sure the nodes should be classes? That seems like an awful lot of structure when all you really seem to need is a bunch of nested dicts:

    root = {
        "foo1": { "bar1": "spam", "bar2": "ham"},
        "foo2": { "baz1": "spam", "baz2": "ham"},
    }
    

    You get the idea.

OK, maybe you're sure that you need the individual nodes to be classes. In that case, they should all inherit from some BaseNode class, right? After all, they are fundamentally similar things.

  • In that case, define a BaseNode.serialise method which effectively prints some information about itself and then calls serialise on all of its children. This is a recursive problem; you might as well use a recursive solution unless your tree is really really really nested.

    The json library allows you to subclass the JSONEncoder to do this.

    >>> import json
    >>> class ComplexEncoder(json.JSONEncoder):
    ...     def default(self, obj):
    ...         if isinstance(obj, complex):
    ...             return [obj.real, obj.imag]
    ...         return json.JSONEncoder.default(self, obj)
    ...
    >>> dumps(2 + 1j, cls=ComplexEncoder)
    '[2.0, 1.0]'
    >>> ComplexEncoder().encode(2 + 1j)
    '[2.0, 1.0]'
    >>> list(ComplexEncoder().iterencode(2 + 1j))
    ['[', '2.0', ', ', '1.0', ']']
    
Sign up to request clarification or add additional context in comments.

1 Comment

Right. The file is originally in a completely unstructured format, but by the time it gets to me, each line is wrapped in a tag, with a root tag at the very start of the file. It's not actually XML, but some crazy antiquated system that's been made to look like XML. (linebreak here) Some of these tags are related to other tags by the order they appear in, and the data contained within. What my parser did was break these tags into their actual structure, called Loops, which I'm needing to then take into a web-friendly format like JSON.
0

Can't suggest anything with JSON, but you can use the Pickle module to serialize your objects in binary format.

1 Comment

Yeah, the problem is I'm needing to use this data on the web, and JSON was the way I was hoping to do that.
0

You might consider using jsonpickle package --- it basically allows you to convert most picklable objects to json.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.