Reputation: 21
What is going on here?
class foo:
def bogh(self):
return "foobar"
class bar:
def gugh(self):
return super().bogh()
foofoo = foo.bar()
print(foofoo.gugh()) # throws AttributeError: 'super' object has no attribute 'bogh'
It seems like it should work, right? Doesn't the super() object return a proxy object containing the parent class's functions and attributes? But it doesn't have them. I ran a dir() on the super() class, and it gave me this:
['__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__']
No trace of the bogh() function.
However, I can get it to work if I de-"nest" the functions, like this:
class foo:
def bogh(self):
return "foobar"
class bar(foo):
def gugh(self):
return super().bogh()
foofoo = bar()
print(foofoo.gugh()) # prints "foobar"
Why doesn't it work if the classes are "nested"? And is there a way to get it to work?
Upvotes: 1
Views: 661
Reputation: 9597
It doesn't work because nesting classes is different than inheriting classes.
If bar
would inherit from foo
, then indeed super()
would work as intended.
But nesting has nothing to do with inheritance, and therefore class bar
does not gain access to any of the methods of foo
.
The point of nesting is merely to control visibility. So in your code example, the nesting makes the strong case that class bar
really doesn't make any sense outside of class foo
and therefore doesn't deserve to be its own top-level class.
So again, summary: Nesting does not imply inheritance and therefore doesn't establish a parent-child relationship between classes.
Btw: In your de-nested example, there's no need to actually call super()
. The whole point of inheritance is to enable automated message delegation. This code works just as well:
class foo:
def bogh(self):
return "foobar"
class bar(foo):
def gugh(self):
return self.bogh() # No need for super
foofoo = bar()
print(foofoo.gugh()) # prints "foobar"
Upvotes: 3