Question about accessing class-attributes.

Alex Martelli aleax at aleax.it
Wed Apr 30 18:31:05 EDT 2003


<posted & mailed>

Michele Simionato wrote:

> Bjorn Pettersen wrote:
>> > Michele Simionato wrote:
>> > I must say, however, that len(S) is not *literally*
>> > type(S).__len__(S):
>> 
>> Yes, that was one of my problems. Where did you find this rule? I can't
>> find a real reference to it anywhere. For classic classes lookup is
>> o.__class__.__dict__['attr'].__get__(o.__class__, o) for regular
>> methods, which sort of looks like the above, but...
> 
> Never found any official reference except postings from Alex Martelli,

Well, my posts aren't *official* references, of course.

> and
> maybe I have read that in the Nutshell, too (Alex, correct me if I am
> wrong!)

Actually this is a tidbit I chose to explain textually instead (p. 87):
"In the new-style object model, implicit use of special methods always
relies on the class-level binding of the special method, if any", and
then a short example of the difference between classic and new-style
in this regard.

In the earlier part about the *classic* object model, p. 78, I do give:

    x.__class__.__dict__['name'](x, arg)

as being "just like" x.name(arg), but the previous paragraph does say
I'm talking of "a typical method call" and that 'name' is "naming one
of x's methods (a function-valued attribute of x's class)", so the
issue of __get__ [which wouldn't work in 2.1 -- I'm trying to cover
BOTH 2.1 and 2.2 in the part about the classic object model!] does
not need to enter the picture.

> I do agree with you that the rule does not work in the case you pointed
> out;
> not sure if it is a bug or intended behaviour.

Me neither.  It MIGHT be an "unavoidable [or too-hard-to-avoid:-)]
implementation restriction", too.  But it does need to be documented
even in that case, at least as long as it holds, I believe.


> With meta-metaclasses you may implement type(S).__len__(S) but
> I see now that your point is more with len(S) that does not
> recognizes '__len__' methods provided indirectly via __getattr__ .
> You can always do that
> 
> class Super(super):
>     def __getattr__(self,somename):
>         return somename
>       
> or even overrides __getattribute__ and implement an entirely
> different version of super. Anyway, this does not solve your
> problem.

Right.  The problem is that the special-method names must be
in the class dictionary at the time type.__new__ runs for it,
in order for the slots in the type object to be set.  They may
be set in various ways, but won't be set at all if the name
isn't in the class dictionary [or the name or slot gets
inherited from one of the class's bases] at the right time.


> It seems to me more a problem of len that of super,
> in the sense that len(x) is not *literally* type(x).__len__(x)
> (idem for __getitem__ in the other thread; I would expect the
> same for str and repr, I should check ...)

I think all of these built-ins go right for the jugular, i.e.,
the appropriate slot in the type object.  And I do NOT think that
is "a problem"... as long as the slot is set "correctly".  I do
wonder if the current non-setting in such advanced cases CAN be
deemed "correct", though.


Alex





More information about the Python-list mailing list