Tuesday, March 29, 2005

When a tuple isn't enough

Using a tuple to pass aggregated date around is a Good Thing, but if you do it a lot or your tuple gets large then you should really use a class. Or should you?

NamedTuple lets you write code like this:

names = ("name", "age", "height")
person1 = NamedTuple(zip(names, ["James", "26", "185"]))
person2 = NamedTuple(zip(names, ["Sarah", "24", "170"]))

print person1.name
for i,name in enumerate(names): print name, ":", person2[i]
Okay, that's pretty ugly. But reading the comments of a related recipe led me to Ganesan Rajogpal's attrdict:
class attrdict(dict):
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        self[name] = value

data = attrdict(red=1, green=2, blue=3)
print data.red
data.black = 4
Much cleaner to use, as well as less code to implement. (Although not immutable, so you couldn't use an attrdict as a key in another dict.) Sort of a nice way to make an annonymous class-like structure for those times when you don't need the real thing. Sort of like a struct for those of you who cut your teeth on C.

There's more along these lines in the cookbook, but attrdict is the one I'm most likely to use.

No comments: