tags:

views:

164

answers:

5

I'm a C programmer and I'm getting quite good with Python. But I still have some problems getting my mind around the OO awesomeness of Python.

Here is my current design problem:

The end "product" is a JSON data structure created in Python (and passed to Javascript code) containing different types of data like:

{ type:url, {urlpayloaddict) }
{ type:text, {textpayloaddict}
...

My Javascript knows how to parse and display each type of JSON response.

I'm happy with this design. My question comes from handling this data in the Python code.

I obtain my data from a variety of sources: MySQL, a table lookup, an API call to a web service... Basically, should I make a super class responseElement and specialise it for each type of response, then pass around a list of these objects in the Python code OR should I simply pass around a list of dictionaries that contain the response data in key value pairs. The answer seems to result in significantly different implementations.

I'm a bit unsure if I'm getting too object happy ??

+5  A: 

In my mind, it basically goes like this: you should try to keep things the same where they are the same, and separate them where they're different.

If you're performing the exact same operations on and with the data, and it can all be represented in a common format, then there's no reason to have separate objects for it - translate it into a common format ASAP and Don't Repeat Yourself when it comes to implementing things that don't distinguish.

If each type/source of data requires specialized operations specific to it, and there isn't much in the way of overlap between such at the layer your Python code is dealing with, then keep things in separate objects so that you maintain a tight association between the specialized code and the specific data on which it is able to operate.

Amber
+3  A: 

Do the different response sources represent fundamentally different categories or classes of objects? They don't appear to, the way you've described it.

Thus, various encode/decode functions and passing around only one type seems the best solution for you.

That type can be a dict or your own class, if you have special methods to use on the data (but those methods would then not care what input and output encodings were), or you could put the encode/decode pairs into the class. (Decode would be a classmethod, returning a new instance.)

Roger Pate
+1: The question says "specialise it for each type of response", but that seems to mean each format or source, not each actual type. This answer has the right question: are they really different classes based on **behavior** or **structure**? If they all behave the same, then they're the same class, irrespective of their origin.
S.Lott
A: 

I've had success with the OOP approach. Consider a base class with a "ToJson" method and have each subclass implement it appropriately. Then your higher level code doesn't need to know any detail about how the data was obtained...it just knows it has to call "ToJson" on every object in the list you mentioned.

A dictionary would work too, but it requires your calling code to know names of keys, etc and won't scale as well.

OOP I say!

Nick Monkman
+1  A: 

Personally, I opt for the latter (passing around a list of data) wherever and whenever possible. I think OO is often misused/abused for certain things. I specifically avoid things like wrapping data in an object just for the sake of wrapping it in an object. So this, {'type':'url', 'data':{some_other_dict}} is better to me than:

class DataObject:
    def __init__(self):
        self.type = 'url'
        self.data = {some_other_dict}

But, if you need to add specific functionality to this data, like the ability for it to sort its data.keys() and return them as a set, then creating an object makes more sense.

sberry2A
+2  A: 

Your receiver objects (which can perfectly well be instances of different classes, perhaps generated by a Factory pattern depending on the source of incoming data) should all have a common method that returns the appropriate dict (or other directly-JSON'able structure, such as a list that will turn into a JSON array).

Differently from what one answer states, this approach clearly doesn't require higher level code to know what exact kind of receiver it's dealing with (polymorphism will handle that for you in any OO language!) -- nor does the higher level code need to know "names of keys" (as, again, that other answer peculiarly states), as it can perfectly well treat the "JSON'able data" as a pretty opaque data token (as long as it's suitable to be the argument for a json.dumps later call!).

Building up and passing around a container of "plain old data" objects (produced and added to the container in various ways) for eventual serialization (or other such uniform treatment, but you can see JSON translation as a specific form of serialization) is a common OO pattern. No need to carry around anything richer or heavier than such POD data, after all, and in Python using dicts as the PODs is often a perfectly natural implementation choice.

Alex Martelli