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