Home > Blockchain >  Invisible attribute of super()'s returned class (Inheritance)
Invisible attribute of super()'s returned class (Inheritance)

Time:11-05

Look at this simple code that uses inheritance:

class A:
    def f(self):
        pass
class B(A):
    def __init__(self):
        pass
b = B()
print(dir(b))

As expected, this list includes the method f and the output is

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'f']

But now, look at this code instead:

class A:
    def f(self):
        pass

class B(A):
    def __init__(self):
        global s
        s = super()
b = B()
print(dir(s))
print(s.f)

The output is

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__self_class__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__thisclass__']

which does not include the function f.

But then, after running the line print(s.f), the output is <bound method A.f of <__main__.B object at 0x00000*******>>

So my question is, how come s.f is not an AttributeError, even though dir(s) does not say it has an f attribute/method?
I'm using IPython7.19.0 over python3.9.7

CodePudding user response:

As per the docs, Python dir()

If the object does not provide dir(), the function tries its best to gather information from the object’s dict attribute, if defined, and from its type object. The resulting list is not necessarily complete and may be inaccurate when the object has a custom getattr().

Also, as per the docs Python super()

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class.

The object-or-type determines the method resolution order to be searched. The search starts from the class right after the type.

Hence, s.f is delegated to the <bound method A.f of <__main__.B object at 0x00000*******>>

Here is an excellent explanation of super(), https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

  • Related