Welcome, guest | Sign In | My Account | Store | Cart

This supclass of dict allows access the the value using attribute access syntax.

d = AttrDict()
d.one = "one"
print d
print d.get
print d.one
print d["one"]
d["two"] = 2
print d.two
print d["two"]
Python, 31 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class AttrDict(dict):
	"""A dictionary with attribute-style access. It maps attribute access to
	the real dictionary.  """
	def __init__(self, init={}):
		dict.__init__(self, init)

	def __getstate__(self):
		return self.__dict__.items()

	def __setstate__(self, items):
		for key, val in items:
			self.__dict__[key] = val

	def __repr__(self):
		return "%s(%s)" % (self.__class__.__name__, dict.__repr__(self))

	def __setitem__(self, key, value):
		return super(AttrDict, self).__setitem__(key, value)

	def __getitem__(self, name):
		return super(AttrDict, self).__getitem__(name)

	def __delitem__(self, name):
		return super(AttrDict, self).__delitem__(name)

	__getattr__ = __getitem__
	__setattr__ = __setitem__

	def copy(self):
		ch = AttrDict(self)
		return ch

It can be easier to read and type data access using the simpler attribute syntax (one dot), that using a lot of square-brackets and quotes. Of course, your key must match a valid identifier string for this to work. If it doesn't you can still use the traditional item access syntax.

4 comments

runsun pan 15 years, 10 months ago  # | flag

copy() failed.

>>> aa = AttrDict()
>>> aa.x = [4,5,6]
>>> aa.x
[4, 5, 6]

>>> bb=aa.copy()
>>> bb.x
[4, 5, 6]

>>> bb.x[1]='X'
>>> bb.x
[4, 'X', 6]
>>> aa.x
[4, 'X', 6]
runsun pan 15 years, 10 months ago  # | flag

a better copy. That seems to be the default feature of the standard dict. Check out a recipe that I just posted for a better way of copying:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473790

runsun pan 15 years, 10 months ago  # | flag

similar and much simpler. Jimmy Retzlaff (other recipes)

Last Updated: 2005/01/03

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/361668

Ricardo J. Murillo 9 years, 9 months ago  # | flag

If I have a multilevel dict I can't access the nested values:

d = AttrDict({'a' : {'b' : 10}})
print d.a.b # Fails

Just replace the __getitem__ method with this:

def __getitem__(self, name):
    item = super(AttrDict, self).__getitem__(name)
    return AttrDict(item) if type(item) == dict else item

print d.a.b # Works
Created by Keith Dart on Thu, 26 Jan 2006 (PSF)
Python recipes (4591)
Keith Dart's recipes (4)

Required Modules

  • (none specified)

Other Information and Tasks