Dictionary of dictionaries vs dictionary of class instances
<p>I understand what a class is, a bundle of attributes and methods stored together in one object. However, i don't think i have ever really grasped their full power. I taught myself to manipulate large volumes of data by using 'dictionary of dictionary' data structures. I'm now thinking if i want to fit in with the rest of the world then i need to implement classes in my code, but i just don't get how to make the transition.</p>

<p>I have a script which gets information about sales orders from a SQL query, performs operations on the data, and outputs it to a csv.</p>

<p>1) (the way i currently do it, store all the orders in a dictionary of dictionaries)</p>

<pre><code>cursor.execute(querystring)

# create empty dictionary to hold orders
orders = {}

# define list of columns returned by query
columns = [col[0] for col in cursor.description]

for row in cursor:
    # create dictionary of dictionaries where key is order_id
    # this allows easy access of attributes given the order_id
    orders[row.order_id] = {}
    for i, v in enumerate(columns):
        # add each field to each order
        orders[row.order_id][v] = row[i]

# example operation
for order, fields in orders.iteritems():
    fields['long'], fields['lat'] = getLongLat(fields['post_code'])

# example of another operation
cancelled_orders = getCancelledOrders()
for order_id in cancelled_orders:
    orders[order_id]['status'] = 'cancelled'

# Other similar operations go here...

# write to file here...
</code></pre>

<p>2) (the way i THINK i would do it if i was using classes)</p>

<pre><code>class salesOrder():


    def __init__(self, cursor_row):
        for i, v in enumerate(columns):
            setattr(self, v, cursor_row[i])


    def getLongLat(self, long_lat_dict):
        self.long, self.lat = long_lat_dict[self.post_code]['long'], long_lat_dict[self.post_code]['lat']


    def cancelOrder(self):
        self.status = 'cancelled'


    # more methods here


cursor.execute(querystring)

# create empty dictionary to hold orders
orders = {}

# define list of columns returned by query
columns = [col[0] for col in cursor.description]

for row in cursor:
    orders[row.order_id] = salesOrder(row)
    orders[row.order_id].getLongLat()

# example of another operation
cancelled_orders = getCancelledOrders()
for order_id in cancelled_orders:
    orders[order_id].cancelOrder()

# other similar operations go here

# write to file here
</code></pre>

<p>I just get the impression that i'm not quite understanding the best way to use classes. Have i got the complete wrong idea about how to use classes? Is there some sense to what i'm doing but it needs refactoring? or am i trying to use classes for the wrong purpose?</p>

<p>Classes are mostly useful for coupling data to behaviour, and for providing structure (naming and documenting the association of certain properties, for example).</p>

<p>You're not doing either of those here - there's no real behaviour in your class (it doesn't <em>do</em> anything to the data), and all the structure is provided externally. The class instances are just used for their attribute dictionaries, so they're just a fancy wrapper around your old dictionary.</p>

<p>If you <em>do</em> add some real behaviour (above <code>getLongLat</code> and <code>cancelOrder</code>), or some real structure (other than a list of arbitrary column names and field values passed in from outside), then it makes sense to use a class.</p>

python class dictionary