automatic accessors to a member var dict elements?
Bengt Richter
bokr at oz.net
Fri Oct 15 12:34:35 EDT 2004
On 15 Oct 2004 08:30:02 GMT, Nick Craig-Wood <nick at craig-wood.com> wrote:
>Jeff Shannon <jeff at ccvcorp.com> wrote:
>> class MyClass(object): # ensure a new-style class
>> def __init__(self):
>> self.m_dict = {'one':1, 'two':2, 'three':3}
>> def __getattr__(self, attr):
>> value = self.m_dict.get(attr, None)
>> if value is None:
>> raise AttributeError(attr)
>> return value
>> def __setattr__(self, attr, value):
>> self.m_dict[attr] = value
>>
>> I'm using a new-style class to take advantage of improvements in
>> attribute lookup. For this class, __getattr__()/__setattr__() will only
>> be called if attr isn't found through the normal attribute resolution
>> rules.
>
>It doesn't!
Oops, I missed that too, as I was focusing on the if-value-is-None logic,
>
>>>> class MyClass(object): # ensure a new-style class
>... def __init__(self):
>... self.m_dict = {'one':1, 'two':2, 'three':3}
>... def __getattr__(self, attr):
>... value = self.m_dict.get(attr, None)
>... if value is None:
>... raise AttributeError(attr)
>... return value
>... def __setattr__(self, attr, value):
>... self.m_dict[attr] = value
Maybe:
>>> class MyClass(object): # ensure a new-style class
... def __init__(self):
... object.__setattr__(self, 'm_dict', {'one':1, 'two':2, 'three':3})
... def __getattr__(self, attr):
... if attr == 'm_dict': return object.__getattribute__(self, attr)
... try: return self.m_dict[attr]
... except KeyError: raise AttributeError(attr)
... def __setattr__(self, attr, value):
... self.m_dict[attr] = value
...
>>> mc = MyClass()
>>> mc.two
2
>>> mc.three
3
>>> mc.four
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in __getattr__
AttributeError: four
>>> mc.four = 4
>>> mc.four
4
>>> mc.m_dict
{'four': 4, 'three': 3, 'two': 2, 'one': 1}
>...
>>>> obj = MyClass()
>Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "<stdin>", line 3, in __init__
> File "<stdin>", line 10, in __setattr__
> File "<stdin>", line 5, in __getattr__
> File "<stdin>", line 5, in __getattr__
> File "<stdin>", line 5, in __getattr__
> File "<stdin>", line 5, in __getattr__
> File "<stdin>", line 5, in __getattr__
>[snip]
> File "<stdin>", line 5, in __getattr__
> File "<stdin>", line 5, in __getattr__
>RuntimeError: maximum recursion depth exceeded
>
>I know there is something different about new style classes in this
>area, but thats not it!
>
You can make self.m_dict raise an attribute error too, but then you can't
write your methods with self.m_dict, since that will trigger recursion.
object.__getattribute__(self, 'm_dict') instead.
Bottom line, though: Why use self.m_dict when you get self.__dict__ for free,
along with attribute access? I.e., self.x is effectively self.__dict__['x']
IOW, self.__dict__ works like you went to all that trouble to make self.m_dict work,
unless your class defines class variables or properties that you want to shadow under
all circumstances.
Regards,
Bengt Richter
More information about the Python-list
mailing list