Skip to content

Instantly share code, notes, and snippets.

@sebclaeys
Created September 19, 2011 20:49
Show Gist options
  • Save sebclaeys/1227566 to your computer and use it in GitHub Desktop.
Save sebclaeys/1227566 to your computer and use it in GitHub Desktop.
Python autodict: implicitly create a dictionary instead of raising KeyError + support for object-like dot access + dictionary visitor
# Autodict class
# Create new autodict if accessing undefined key
# support dot access syntax (mydict.test == mydict['test'])
class autodict(dict):
def __getitem__(self, name):
if not name in self:
dict.__setitem__(self, name, autodict())
return dict.__getitem__(self, name)
def __getattr__(self, name):
if name in self.__dict__:
return self.__dict__[name]
else:
return self[name]
def __setattr__(self, name, val):
if name in self.__dict__:
self.__dict__[name] = val
else:
self[name] = val
# Visit function for autodict like structure
# Call the given function on each leaf passing all keys in arguments
def visit(obj, func, lvl=-1, args=[]):
if lvl == 0 or not isinstance(obj, dict):
func(*(args + [obj]))
else:
for key, val in obj.items():
visit(val, func, lvl - 1, args + [key])
Autodicts allow you to use a python dictionary to easily store values with an arbitrary combination of key.
Example:
>>> from autodict import autodict, visit
>>> contact = autodict()
>>> contact.newyork.firends.didier = "3475556677"
>>> contact['newyork']['firends']['ben'] = "3478886677"
>>> contact
{'newyork': {'firends': {'didier': '3475556677', 'ben': '3478886677'}}}
>>> def v(city, role, name, number):
... print "Number for %s from %s: %s" % (name, city, number)
...
>>> visit(contact, v)
Number for didier from newyork: 3475556677
Number for ben from newyork: 3478886677
@aaronchall
Copy link

Actually, the best approach is to implement missing if you want to subclass a dict.

http://stackoverflow.com/a/19829714/541136

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment