dictionary with attribute member access
--HG-- branch : aspn
This commit is contained in:
@@ -1,33 +1,75 @@
|
|||||||
|
# Copyright (c) 2009 Andreas Balogh
|
||||||
|
# See LICENSE for details.
|
||||||
|
|
||||||
|
# http://code.activestate.com/recipes/361668/
|
||||||
# http://code.activestate.com/recipes/473786/
|
# http://code.activestate.com/recipes/473786/
|
||||||
|
# http://groups.google.com/group/comp.lang.python/browse_thread/thread/fa88bba7184d9431
|
||||||
|
|
||||||
class AttrDict(dict):
|
class AttrDict(dict):
|
||||||
"""A dictionary with attribute-style access. It maps attribute access to
|
"""A dict whose items can also be accessed as member variables.
|
||||||
|
|
||||||
|
A dictionary with attribute-style access. It maps attribute access to
|
||||||
the real dictionary. """
|
the real dictionary. """
|
||||||
def __init__(self, init={}):
|
def __init__(self, *args, **kwargs):
|
||||||
dict.__init__(self, init)
|
dict.__init__(self, *args, **kwargs)
|
||||||
|
self.__dict__ = self
|
||||||
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):
|
def copy(self):
|
||||||
ch = AttrDict(self)
|
ch = AttrDict(self)
|
||||||
return ch
|
return ch
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'AttrDict(' + dict.__repr__(self) + ')'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fromkeys(self, seq, value = None):
|
||||||
|
return AttrDict(dict.fromkeys(seq, value))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# test cases provided by Gabriel Genellina
|
||||||
|
from pickle import loads, dumps
|
||||||
|
assert AttrDict() == {}
|
||||||
|
d1 = {1:2, '3':4, 'name': 'value', '__getattr__': 5, '__getitem__': 6}
|
||||||
|
d2 = AttrDict(d1)
|
||||||
|
assert d1 == d2
|
||||||
|
|
||||||
|
assert d2.copy() == d2
|
||||||
|
assert isinstance(d2.copy(), type(d2))
|
||||||
|
assert eval(repr(d2)) == d2
|
||||||
|
assert isinstance(eval(repr(d2)), type(d2))
|
||||||
|
|
||||||
|
d3 = AttrDict.fromkeys([1,2,3])
|
||||||
|
assert isinstance(d3, AttrDict)
|
||||||
|
assert d3 == {1:None, 2:None, 3:None}
|
||||||
|
|
||||||
|
assert d2[1] == 2
|
||||||
|
assert d2['name'] == d2.name == 'value'
|
||||||
|
assert d2.__getattr__ == 5
|
||||||
|
|
||||||
|
assert not hasattr(d2, 'xyz')
|
||||||
|
assert 'xyz' not in d2
|
||||||
|
d2.xyz = 123
|
||||||
|
assert d2.xyz == d2['xyz'] == 123
|
||||||
|
assert 'xyz' in d2
|
||||||
|
|
||||||
|
d2['xyz'] = 456
|
||||||
|
assert d2['xyz'] == d2.xyz == 456
|
||||||
|
assert hasattr(d2, 'xyz')
|
||||||
|
|
||||||
|
d2['abc'] = 789
|
||||||
|
assert d2.abc == d2['abc'] == 789
|
||||||
|
|
||||||
|
d2.abc = 123
|
||||||
|
assert d2.abc == d2['abc'] == 123
|
||||||
|
|
||||||
|
del d2.abc
|
||||||
|
assert not hasattr(d2, 'abc')
|
||||||
|
assert 'abc' not in d2
|
||||||
|
del d2['xyz']
|
||||||
|
assert not hasattr(d2, 'xyz')
|
||||||
|
assert 'xyz' not in d2
|
||||||
|
|
||||||
|
d4 = loads(dumps(d2))
|
||||||
|
assert d2 == d4
|
||||||
|
assert isinstance(d4, type(d2))
|
||||||
Reference in New Issue
Block a user