2

I am puzzled with the following error in python 2.7.12 Suppose we have a class definition within a class, something similar to this:

class C(object):
    def __init__(self):
        print "class C"


class D(object):
    def __init__(self):
        print "class D"


class A(D):

    class B(C):
        def __init__(self):
            # Strangely here B is "not defined", why?
            super(B, self).__init__()
            print "class B"

    def __init__(self):
        super(D, self).__init__()
        print "class A"

    def do_something(self):
        b_class = self.B()
        print "b_class within A : {}".format(b_class)


a_class = A()
a_class.do_something()

but if we we extract the definition of class B outside the scope of class A, everything works well.

Do we need to use "super" differently when called within a nested class? I fail to understand why its usage would be different within or outside the nested class. Any pointers?

1
  • 2
    Any pointers? There are no pointers in Python ;) Commented Nov 7, 2016 at 14:00

2 Answers 2

7

The problem is not the subclass or superclass, but the nesting. B itself is not defined, only A.B is.

Note that in Python there is almost never a good reason to nest classes, though.

Sign up to request clarification or add additional context in comments.

1 Comment

Indeed that is the case, although I would have thought that super implicitly took the context into account...
4

You need to address B by its full name, A.B:

class C(object):
    def __init__(self):
        print "class C"


class D(object):
    def __init__(self):
        print "class D"


class A(D):

    class B(C):
        def __init__(self):
            super(A.B, self).__init__()
            print "class B"

    def __init__(self):
        super(D, self).__init__()
        print "class A"

    def do_something(self):
        b_class = self.B()
        print "b_class within A : {}".format(b_class)


>>> a_class = A()
>>> a_class.do_something()

class A
class C
class B
b_class within A : <__main__.B object at 0x7f0cac98cbd0>

1 Comment

@Leon that's because A.__init__ calls super(D, self).__init__(), which means "calls the __init__ of D superclass" (in this case object.__init__). If you want to invoke D.__init__ from A.__init__, you have to use super(A, self).__init__() instead ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.