Python 2.2, creating new types from base types
Jason Orendorff
jason at jorendorff.com
Fri Jan 18 01:37:04 EST 2002
Peter,
> It seems like it should work, but doesn't..... Certainly being
> able to subclass dict to come up with a specialised form of
> dict should be achievable using the new features.
I don't think you need to subclass dict here. You might be
more comfortable with the semantics of UserDict.
When you write x['a']['b']['c'], Python basically does
x.__getitem__('a').__getitem__('b').__getitem__('c') .
If you want to attach special behavior to only the 2nd
__getitem__ call, you need to make sure that the first
__getitem__ call returns an object that has that
special behavior.
Here's my stab at it. You'll want to modify my __getitem__()
method where it says "elif self.depth == 2: ..."
## Jason Orendorff http://www.jorendorff.com/
from UserDict import UserDict
class MyDict(UserDict):
def __init__(self, data=None, depth=3):
UserDict.__init__(self)
self.depth = depth
if data is not None:
if not hasattr(data, 'iteritems'):
# Convert data to a dict first.
data = dict(data)
self.update(data)
def __getitem__(self, key):
""" Get a sub-dictionary. Sneakily create one if none yet exists
for the given key.
"""
try:
return self.data[key]
except KeyError:
if self.depth > 2:
x = self.data[key] = MyDict(depth=self.depth - 1)
elif self.depth == 2:
x = self.data[key] = {}
else:
raise
return x
def update(self, other):
for k, v in other.iteritems():
self[k].update(v)
>>> from MyDict import MyDict
>>> m = MyDict({'a' : {'b': {'c': 14434, 'd': 66341}}})
>>> m
{'a': {'b': {'c': 14434, 'd': 66341}}}
>>> m['a']['b']['c']
14434
>>> m['d']['e']['f'] = 95832
>>> m
{'a': {'b': {'c': 14434, 'd': 66341}}, 'd': {'e': {'f': 95832}}}
>>> m['d'].__class__
<class udict.MyDict at 0x00A4FD00>
More information about the Python-list
mailing list