I’ve been doing quite a bit of Python hacking in my recent free time. A couple days ago, I had the desire for a dictionary that I could access key values just like object attribute names. For example, in the dictionary d={'key':'value'}
, I wanted to be able to use d.key
to return 'value'
. I thought this would be a common desire and probably already exists (and might even be built-in somehow), so I went on to #python
and asked the folk there. Nobody knew of anything. So I set off to write my own. I called it AttrDict.
Yesterday, I found something similar already exists. It’s called ObDict. Similar? Very! π But different enough that I continued mine… and have a somewhat complete python module of my own. So far it’s been a nice opportunity to learn more about Python objects and use the unittest
module for unit testing.
It’s not 100% coverage of the dict interface, but it’s pretty close and I think it’s usable enough that I can slap a quick release together and work on other stuff. Bugs/patches/testing/suggestions welcome.
- Grab the source: AttrDict-0.1.zip
- Browse the source: http://stevenbrown.ca/src/AttrDict/
- Branch the source:
bzr branch http://stevenbrown.ca/src/AttrDict
Update:
Wooops, forgot to write a bit more about it. Here’s the docstring from the module:
as object attributes. This is for convenience. You can do things like this:
d = dict() #standard dict, for comparison
a = AttrDict() #
d[‘ok’] = ‘this is ok’
d.ok -> AttributeError raised
d.ok = ‘test’ -> AttributeError raised
You cannot assign attributes to standard Python dicts.
a[‘ok’] = ‘this is ok’
a.ok -> ‘this is ok’ #attribute is automatically created
a.ok = ‘changed’
a[‘ok’] -> ‘changed’ #and the dict value is automatically updated
a.ok2 = ‘new value’ #adding new attribute, ok2
a[‘ok2’] -> ‘new value’ #dict key is automatically created
This introduces a limitation on the dictionary keys such
that they must be strings and provide valid Python syntax for accessing.
For example:
{‘123′:’valid’} #is a valid dictionary
but
mydict.123 #is not valid Python syntax.
Attempting to create a key that cannot be accessed through an attribute name
will raise an AttributeError Exception.
This module has not been built for optmization. Some of the method
documentation has been taken from Python’s dict documentation. For more info
on a particular method, refer to that. I’ve tried to mirror the effects of
the standard dict as closely as possible.
Ooooh… somebody (“forrestv” on #python) suggested a very elegant solution to this which basically makes what I wrote pointless. (Oh well!) I’ll post it shortly… If you’re familiar with Python, maybe you can guess? π
you know it’s gorgeous outside… just sayin
I don’t speak python, but isn’t this what descriptors are for? Those crazy __get__ , __set___, __yawn___….etc.
@Shirley: Yes. And that’s basically how I implemented it… But there’s another (very clever) way. π I’ll leave it open until I get back today, because as @popeko said, it’s gorgeous outside and that’s where I’m headed.
Alright, the solution would basically be this:
class AttrDict(dict):
def __init__(self, *args):
self.__dict__ = self
When this was suggested, I was first like, “Sure, but then you’d have to manually …. oh …. hmmmm…” π Clever. And I’m not sure how many languages you could do this kind of thing in… Shirley, regarding our discussion, I may have to concede that different languages can be quite different in their core design and promote different design choices due to how easy they make tasks – syntax aside – even though pretty much any task can be accomplished in any language (generalization).