Didi Willems
Didi Willems

Reputation: 57

Creating objects within an existing object in Python

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?

Upvotes: 1

Views: 2302

Answers (2)

Aaron
Aaron

Reputation: 2053

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")

Upvotes: 2

rrauenza
rrauenza

Reputation: 6963

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.

Upvotes: 4

Related Questions