Albert-Jan Roskam wrote:

>> From: st...@pearwood.info

>> Fortunately, Python has an mechanism for solving this problem:
>> the `__getattr__` method and friends.
>> 
>> 
>> class ColumnView(object):
>>     _data = {'a': [1, 2, 3, 4, 5, 6],
>>              'b': [1, 2, 4, 8, 16, 32],
>>              'c': [1, 10, 100, 1000, 10000, 100000],
>>              }
>>     def __getattr__(self, name):
>>         if name in self._data:
>>             return self._data[name][:]
>>         else:
>>             raise AttributeError
>>     def __setattr__(self, name, value):
>>         if name in self._data:
>>             raise AttributeError('read-only attribute')
>>         super(ColumnView, self).__setattr__(name, value)
>>     def __delattr__(self, name):
>>         if name in self._data:
>>             raise AttributeError('read-only attribute')
>>         super(ColumnView, self).__delattr__(name)
> 
> That also seems very straightforward. Why does "if name in self._data:"
> not cause a recursion? self._data calls __getattr__, which has self._data
> in it, which...etc.

__getattr__() is only invoked as a fallback when the normal attribute lookup 
fails:

>>> class A(object):
...     def __getattr__(self, name):
...             return self.data[name]
... 
>>> a = A()
>>> a.data = dict(foo="bar")
>>> a.foo
'bar'
>>> del a.data
>>> import sys
>>> sys.setrecursionlimit(10)
>>> a.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __getattr__
  File "<stdin>", line 3, in __getattr__
  File "<stdin>", line 3, in __getattr__
RuntimeError: maximum recursion depth exceeded while calling a Python object

If you need to intercept every attribute lookup use __getattribute__():

>>> class B(A):
...     def __getattribute__(self, name):
...         print "looking for", name
...         return super(B, self).__getattribute__(name)
... 
>>> b = B()
>>> b.data = dict(foo="bar")
>>> b.foo
looking for foo
looking for data
'bar'


_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to