Question about accessing class-attributes.

Alex Martelli aleax at aleax.it
Tue Apr 29 17:59:43 EDT 2003


Bjorn Pettersen wrote:

>> From: Alex Martelli [mailto:aleax at aleax.it]
> [...]
>> > however I haven't been able to find a good description of attribute
>> > lookup for new-style classes... (references?) E.g. why is
>> > the metaclass' __getattr__ never called?
   ...
> Here's the case I'm confused about:

[special-methods problem snipped]

Ah yes, I see now!  Yes, functions such as len() rely on slots in
the type object, e.g. as you've noticed:

> finding the function they're needing, e.g. for len, it looks like it
> uses:
> 
>   m = o->ob_type->tp_as_sequence;
>   if (m && m->sq_length)
>     return m->sq_length(o);
> 
>   return PyMapping_Size(o);

and the "incredibly complex thinking" (quoting from typeobject.c)
in update_one_slot doesn't seem to work except for operations the
which "the class overrides in its dict" (again from a comment in
typeobject.c, this one for fixup_slot_dispatchers).

The issue may be with _PyType_Lookup (again in the same ,c file),
which just gives up if it can't find a name somewhere along the mro
(it doesn't "look upwards" to the metaclass) while type_getattro
DOES work upwards on the metaclass too.  Hmmmm.  I'm not sure I
really understand all that's going on here - it IS a rather hairy
zone of the code.  Maybe you can post this as a bug in 2.3 beta 1
on sourgeforge (ideally showing where in the docs it defines the
semantics that it then doesn't respect) so we can get this looked
at by the few people who really DO grasp these parts...;-).  There
is probably some sound implementation reason for the current
behavior, but if so it should be better documented, I think.


> which would never call the metaclass' __getattr__ (since tp_as_sequence
> would presumably be NULL?).
> 
> The relevance this has to super, is that you couldn't do a (contrived)
> example like:
> 
>   for item in super(MyClass, self):
>       ...
> 
> (in general, you can't pass super(MyClass, self) to a function expecting
> a MyClass instance, even if MyClass defines no new behavior...)

Yes, of course not -- super(MyClass, self) is NOT an instance of MyClass
(isn't THAT why you're calling super...?).  

> 
> Perhaps a more realistic exmaple?:
> 
>   class Secure(object):
>     def __init__(self, name):
>       self.name = name
>   
>     def __getattr__(self, attr):
>       return getSecureMethod(self.name, attr, getUserPrivileges())
>         
>   class LogFoo(Secure):
>     def __init__(self):
>       Secure.__init__(self, 'SalaryDB')
>       
>     def foo(self):
>       print 'calling foo'
>       return super(LogFoo, self).foo()
>       
>   lf = LogFoo()
>   print lf.foo()

Sorry, I don't get it.  How is this related to metaclasses...?


Alex





More information about the Python-list mailing list