GrelEns wrote:
> hello,> > i would like if this behaviour can be obtained from python : trap an> attributeError from inside a subclassing dict class... (here is a silly> examples to explain my question)> > class Test(dict):> """subclassing a dict and each key will permit access to a tuple of fized> size"""> def __init__(self):> pass> def load(self, adict):> """actually it will be done from a text file with fixed size fields,> each> tuple will have the same size"""> for k in adict:> self[k] = tuple(adict[k])> > t = Test()> t.load({1: ('a', 'aa'), 2: ('(b', 'bb')})> > here is what i would have :>>>> t[1].get('first')> 'a'> > without having to define tuple as an object or subclassing tuple, of> course now i had :>>>> t[1].get('first')> > Traceback (most recent call last):> File "<pyshell#15>", line 1, in -toplevel-> t['A'].get('first')> AttributeError: 'tuple' object has no attribute 'get'> > is it possible ?> > btw my question is something like is there a way from inside Test code to> say to python that when it first get t[1] it should not go further, trap> the things one ask to do on t[key] and then calling a function such as> > (inside Test)> def __get(self, key, readable):> mapping = {'first' : 1, 'second' : 2}> return self[key][mapping[readable]]> > (maybe it is a silly design...but i need this because i do want some kind> of readable object access without having to create all these objects)
Here's one way to do it:
>>> class Dict(dict):
... translate = {"first": 0, "second": 1}
... def __getitem__(self, key):
... value = dict.__getitem__(self, key[0])
... return value[self.translate[key[1]]]
...
>>> d = Dict([(1,("a", "aa")), (2, ("b", "bb"))])>>> d[1, "first"]
'a'
>>> d[2, "second"]
'bb'
Here's another:
>>> class Dict(dict):
... def __getitem__(self, key):
... return Wrap(dict.__getitem__(self, key))
...
>>> class Wrap(object):
... def __init__(self, data): self.data = data
... first = property(lambda self: self.data[0])
... second = property(lambda self: self.data[1])
...
>>> d = Dict([(1,("a", "aa")), (2, ("b", "bb"))])>>> d[1].first
'a'
>>> d[2].second
'bb'
>>>
Note that you might end with *more* objects as every call to __getitem__()
creates a new Wrap instance. A cache could help, but if you did it properly
with a custom class for the values the problem wouldn't arise.
Personally, I would put custom objects into a normal dictionary instead of
playing one of these tricks.
Peter