Skip to content Skip to sidebar Skip to footer

Should I Use A Class Or Dictionary?

I have a class that contains only fields and no methods, like this: class Request(object): def __init__(self, environ): self.environ = environ self.request_met

Solution 1:

Use a dictionary unless you need the extra mechanism of a class. You could also use a namedtuple for a hybrid approach:

>>>from collections import namedtuple>>>request = namedtuple("Request", "environ request_method url_scheme")>>>request
<class '__main__.Request'>
>>>request.environ = "foo">>>request.environ
'foo'

Performance differences here will be minimal, although I would be surprised if the dictionary wasn't faster.

Solution 2:

A class in python is a dict underneath. You do get some overhead with the class behavior, but you won't be able to notice it without a profiler. In this case, I believe you benefit from the class because:

  • All your logic lives in a single function
  • It is easy to update and stays encapsulated
  • If you change anything later, you can easily keep the interface the same

Solution 3:

Why would you make this a dictionary? What's the advantage? What happens if you later want to add some code? Where would your __init__ code go?

Classes are for bundling related data (and usually code).

Dictionaries are for storing key-value relationships, where usually the keys are all of the same type, and all the values are also of one type. Occasionally they can be useful for bundling data when the key/attribute names are not all known up front, but often this a sign that something's wrong with your design.

Keep this a class.

Solution 4:

I think that the usage of each one is way too subjective for me to get in on that, so i'll just stick to numbers.

I compared the time it takes to create and to change a variable in a dict, a new_style class and a new_style class with slots.

Here's the code i used to test it(it's a bit messy but it does the job.)

import timeit

classFoo(object):

    def__init__(self):

        self.foo1 = 'test'
        self.foo2 = 'test'
        self.foo3 = 'test'defcreate_dict():

    foo_dict = {}
    foo_dict['foo1'] = 'test'
    foo_dict['foo2'] = 'test'
    foo_dict['foo3'] = 'test'return foo_dict

classBar(object):
    __slots__ = ['foo1', 'foo2', 'foo3']

    def__init__(self):

        self.foo1 = 'test'
        self.foo2 = 'test'
        self.foo3 = 'test'

tmit = timeit.timeit

print'Creating...\n'print'Dict: ' + str(tmit('create_dict()', 'from __main__ import create_dict'))
print'Class: ' + str(tmit('Foo()', 'from __main__ import Foo'))
print'Class with slots: ' + str(tmit('Bar()', 'from __main__ import Bar'))

print'\nChanging a variable...\n'print'Dict: ' + str((tmit('create_dict()[\'foo3\'] = "Changed"', 'from __main__ import create_dict') - tmit('create_dict()', 'from __main__ import create_dict')))
print'Class: ' + str((tmit('Foo().foo3 = "Changed"', 'from __main__ import Foo') - tmit('Foo()', 'from __main__ import Foo')))
print'Class with slots: ' + str((tmit('Bar().foo3 = "Changed"', 'from __main__ import Bar') - tmit('Bar()', 'from __main__ import Bar')))

And here is the output...

Creating...

Dict: 0.817466186345Class: 1.60829183597Class_with_slots: 1.28776730003

Changing a variable...

Dict: 0.0735140918748Class: 0.111714198313Class_with_slots: 0.10618612142

So, if you're just storing variables, you need speed, and it won't require you to do many calculations, i recommend using a dict(you could always just make a function that looks like a method). But, if you really need classes, remember - always use __slots__.

Note:

I tested the 'Class' with both new_style and old_style classes. It turns out that old_style classes are faster to create but slower to modify(not by much but significant if you're creating lots of classes in a tight loop (tip: you're doing it wrong)).

Also the times for creating and changing variables may differ on your computer since mine is old and slow. Make sure you test it yourself to see the 'real' results.

Edit:

I later tested the namedtuple: i can't modify it but to create the 10000 samples (or something like that) it took 1.4 seconds so the dictionary is indeed the fastest.

If i change the dict function to include the keys and values and to return the dict instead of the variable containing the dict when i create it it gives me 0.65 instead of 0.8 seconds.

classFoo(dict):
    pass

Creating is like a class with slots and changing the variable is the slowest (0.17 seconds) so do not use these classes. go for a dict (speed) or for the class derived from object ('syntax candy')

Solution 5:

I agree with @adw. I would never represent an "object" (in an OO sense) with a dictionary. Dictionaries aggregate name/value pairs. Classes represent objects. I've seen code where the objects are represented with dictionaries and it's unclear what the actual shape of the thing is. What happens when certain name/values aren't there? What restricts the client from putting anything at all in. Or trying to get anything at all out. The shape of the thing should always be clearly defined.

When using Python it is important to build with discipline as the language allows many ways for the author to shoot him/herself in the foot.

Post a Comment for "Should I Use A Class Or Dictionary?"