RE: [Python-Dev] Attribute lookup (was Re: python-dev Summary for 2003-05-01 through 2003-05-15)

At 12:25 AM 5/20/03 -0600, Bjorn Pettersen wrote:
From: Phillip J. Eby [mailto:pje@telecommunity.com]
1. First, the class/type and its bases are searched, checking dictionaries only.
2. If the object found is a "data descriptor" (i.e. has a type with a non-null tp_descr_set pointer, which is closely akin to whether the descriptor has a '__set__' attribute), then the data descriptor's __get__ method is invoked.
3. If the object is not found, or not a data descriptor, the instance dictionary is checked. If the attribute isn't in the instance dictionary, then the descriptor's __get__ method is invoked (assuming a descriptor was found).
4. Invoke __getattr__ if present.
(Note that replacing __getattribute__ *replaces* this entire algorithm.)
Also note that special methods are *not* handled specially here. The behavior Aahz is referring to is that slots (e.g. tp_call) on new-style types do not retrieve an instance attribute; they are based purely on class-level data. [...]
Wouldn't that be explicitly specified class-level data, i.e. it circumvents the __getattr__ hook completely:
I was focusing on the documenting the attribute lookup behavior, not the "special methods" behavior. :) My point was only that "special methods" aren't implemented via attribute lookup, so the attribute lookup rules don't apply.
this makes it impossible to implement a __getattr__ anywhere that intercepts len(obj):
class meta(type): .. def __getattr__(self, attr): .. if attr == '__len__': .. return lambda:42 .. class C(object): .. __metaclass__ = meta .. C.__len__() 42 c = C() len(c) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() of unsized object len(C) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() of unsized object
The meta example would have to work to be able to create "true" proxy objects(?)
You can always do this: class C(object): def __len__(self): return self.getLength() def __getattr__(self,attr): if attr=='getLength': return lambda: 42 if you really need to do that.
Is this intended behaviour?
You'd have to ask Guido that.
participants (1)
-
Phillip J. Eby