git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How does the super type present itself and do lookups?


On 23/03/20 7:40 pm, Adam Preble wrote:
> I don't doubt what you got from the source, but I am trying to figure
> out how I could have inferred that from the code I was trying. It
> looks like child_instance.__getattribute__ ==
> child_instance.super().__getattribute__.

Don't feel too bad, it took me a while to figure out what was
happening here myself!

I think the problem is that the act of looking up __getattribute__
on the super object invokes the super object's magic lookup
machinery, and ends up giving a misleading result.

It's clearer if you look for __getattribute__ directly on the
*class* of the super object. I tried this experiment:

class C:

     a = "a in C"

class D(C):

     a = "a in D"

     def getsuper(self):
         return super()

d = D()
s = d.getsuper()
print("type(d).__getattribute__ =", type(d).__getattribute__)
print("type(s).__getattribute__ =", type(s).__getattribute__)

Result:

type(d).__getattribute__ = <slot wrapper '__getattribute__' of 'object' 
objects>
type(s).__getattribute__ = <slot wrapper '__getattribute__' of 'super' 
objects>

If you try this with __getattr__ you find that super objects
don't even have one:

print("type(s).__getattr__ =", type(s).__getattr__)

gives

AttributeError: type object 'super' has no attribute '__getattr__'

Another way to see this is to look at the class dict of the super
object:

print(list(type(s).__dict__.keys()))

gives

['__repr__', '__getattribute__', '__get__', '__init__', '__new__', 
'__thisclass__', '__self__', '__self_class__', '__doc__']

from which it's clear that the super object overrides __getattribute__
but not __getattr__.

-- 
Greg