2

I would like to create an object that holds and creates different objects within itself. I have an outer class and inner classes, like this:

class Outer:
    def __init__(self, name):
        self.name = name

    def sayHello(self):
        print "Hello " + self.name

    class Inner1:
        def __init__(self, name):
            self.name = name

    class Inner2(Inner1):
        pass

    class Inner3(Inner1):
        pass
new = outer("new")

And then new needs to make on object of inner2 or inner3... I tried it with new.inner2() but I don´t get the result I want. Any tips?

Mark Chackerian
  • 21,866
  • 6
  • 108
  • 99
  • 3
    1. Why do you have nested classes? 2. Given that it's named `Inner2` not `inner2`, why did you try `new.inner2()`? – jonrsharpe Jun 17 '16 at 14:21
  • The names are just for example. I want an object thats individual and can becreated by the user and that object should be able to make other objects within itself. allso provided by the user. because i want the new object to make a new innerclass. – Didi Willems Jun 17 '16 at 14:26
  • I don't understand what you're trying to achieve. Could you give some context; what problem are you actually trying to solve? Nested classes are rarely necessary in Python, and the only problem with your code so far is that: 1. it isn't syntactically valid without `pass` in the bodies of the nested subclasses; and 2. you're not typing the class name in the correct case. – jonrsharpe Jun 17 '16 at 14:27
  • Are you trying to instantiate an `Inner1` in the global scope? – ddsnowboard Jun 17 '16 at 14:35

2 Answers2

4

Here is how you would do nested classes and nested instantiations. When you're embedding the classes, you're only embedding the types. You have to create the instances in self.__init__

(If you're trying to do global inner instances shared among all Outer instances please update your question.)

class Outer(object):

    class Inner1(object):
        pass

    class Inner2(Inner1):
        pass

    class Inner3(Inner2):
        pass

    def __init__(self):
        self.inner1 = Outer.Inner1()
        self.inner2 = Outer.Inner2()
        self.inner3 = Outer.Inner3()

outer = Outer()

print outer.inner1
print outer.inner2
print outer.inner3

Note that you don't have to actually use nested classes for this -- your classes can be defined outside of your class, and is sometimes preferred as simpler and more Pythonic:

class Inner1(object):
    pass

class Inner2(Inner1):
    pass

class Inner3(Inner2):
    pass

class Outer(object):

    def __init__(self):
        self.inner1 = Inner1()
        self.inner2 = Inner2()
        self.inner3 = Inner3()

outer = Outer()

print outer.inner1
print outer.inner2
print outer.inner3

Sometimes you'll also see a pattern of...

class Inner1(object):
   pass

class Outer(object):
   Inner1 = Inner1

to make a "handy" reference to the class inside the class. This is often used with custom exceptions that the class might throw.

There are many different opinions on whether nesting the classes is preferred.

Community
  • 1
  • 1
rrauenza
  • 6,285
  • 4
  • 32
  • 57
2

Honestly inner classes are not generally a good idea, especially if you're instantiating them outside of the "containing" class.

But to answer your question, basically the inner class is just declared in a different scope, so you need to reference the scope it is in.

# Changed to a capitol letter as that is more conventional
class Outer:
    name = ""

    def __init__(self, name):
        self.name = name

    def sayHello(self):
        print ("Hello" + self.name)

    class Inner1:
        def __init__(self, name):
            self.name = name

    class Inner2(Inner1):
        pass

    class Inner3(Inner1):
        pass

newOuter = Outer("newOuter")
newInner2 = Outer.Inner2("newInner2")
Aaron
  • 1,893
  • 16
  • 24
  • *Honestly inner classes are not generally a good idea, especially if you're declaring them outside of the "containing" class.* -- is this really what you meant to say? What do you mean? – rrauenza Jun 17 '16 at 14:52
  • I meant instantiating, not declaring :) – Aaron Jul 20 '16 at 16:04