Tutorials
python

# Inner Classes in Python

In this basic Python tutorial, you'll learn about why and when you should use inner classes.

You have probably heard of the nested functions in Python. If you know what that means then understanding inner/nested classes is nothing. We will explore some new things in the Inner or Nested classes here.

## 1. Inner or Nested Classes

Inner or Nested Class is defined inside another class. See the structure of inner or nested classes.

## outer class
class Outer:

## inner class
class Inner:
pass

## multilevel inner class
class InnerInner:
pass

## another inner class
class _Inner:
pass

## ...

pass


## 2. Why Inner Classes?

1. Grouping of two or more classes. Suppose you have two classes Car and Engine. Every Car needs an Engine. But, Engine won't be used without a Car. So, you make the Engine an inner class to the Car. It helps save code.

2. Hiding code is another use of Nested classes. You can hide the Nested classes from the outside world.

3. It's easy to understand the classes. Classes are closely related here. You don't have to search for the classes in the code. They are all together.

Inner or Nested classes are not the most commonly used feature in Python. But, it can be a good feature to implement code. The code is straightforward to organize when you use the inner or nested classes.

## 3. Coding Inner Class

Implementing the inner or nested classes is not difficult. You can see the structure of the code here.

You can access the inner class in the outer class using the self keyword. So, you can quickly create an instance of the inner class and perform operations in the outer class as you see fit. You can't, however, access the outer class in an inner class. Let's see an example below.

class Outer:
"""Outer Class"""

def __init__(self):
## instantiating the 'Inner' class
self.inner = self.Inner()

def reveal(self):
## calling the 'Inner' class function display
self.inner.inner_display("Calling Inner class function from Outer class")

class Inner:
"""Inner Class"""

def inner_display(self, msg):
print(msg)


Now, you'll make the instance of the Outer class and call it's reveal() method to execute the Inner class method inner_display().

## creating an instance of the 'Outer' class
outer = Outer()
## calling the 'reveal()' method
outer.reveal()

Calling Inner class function from Outer class


Let's see another way to access the inner class. This way is a little less efficient.

Outer().Inner().inner_display("Calling the Inner class method directly")

Calling the Inner class method directly


What if you want to create an instance of the inner class outside the outer class? Can you do that? Yes, let's see how to make an instance of the inner class outside of the outer class.

outer = Outer()

## instantiating the inner class
inner = outer.Inner() ## inner = Outer().Inner() or inner = outer.inner
inner.inner_display("Just Print It!")

Just Print It!


### 3.1. Multiple Inner Classes

It is a class containing more than one inner class. You can have more than one inner class in a class. As we defined earlier, it's easy to implement multiple inner classes.

class Outer:
"""Outer Class"""

def __init__(self):
## Instantiating the 'Inner' class
self.inner = self.Inner()
## Instantiating the '_Inner' class
self._inner = self._Inner()

def show_classes(self):
print("This is Outer class")
print(inner)
print(_inner)

class Inner:
"""First Inner Class"""

def inner_display(self, msg):
print("This is Inner class")
print(msg)

class _Inner:
"""Second Inner Class"""

def inner_display(self, msg):
print("This is _Inner class")
print(msg)

## ...


Accessing the classes is the same as we did earlier. See the example for better understanding.

## instantiating the classes

## 'Outer' class
outer = Outer()
## 'Inner' class
inner = outer.Inner() ## inner = outer.inner or inner = Outer().Inner()
## '_Inner' class
_inner = outer._Inner() ## _inner = outer._outer or _inner = Outer()._Inner()

## calling the methods
outer.show_classes()

print()

## 'Inner' class
inner.inner_display("Just Print It!")

print()

## '_Inner' class
_inner.inner_display("Just Show It!")

This is Outer class
<__main__.Outer.Inner object at 0x0000021B37962048>
<__main__.Outer._Inner object at 0x0000021B37962160>

This is Inner class
Just Print It!

This is _Inner class
Just Show It!


## 3.2. Multilevel Inner Classes

In multilevel inner classes, the inner class contains another class which inner classes to the previous one. You can see the structure of this hierarchy here:

class Outer:
"""Outer Class"""

def __init__(self):
## instantiating the 'Inner' class
self.inner = self.Inner()
## instantiating the multilevel 'InnerInner' class
self.innerinner = self.inner.InnerInner()

def show_classes(self):
print("This is Outer class")
print(inner)

## inner class
class Inner:
"""First Inner Class"""

def __init__(self):
## instantiating the 'InnerInner' class
self.innerinner = self.InnerInner()

def show_classes(self):
print("This is Inner class")
print(self.innerinner)

## multilevel inner class
class InnerInner:

def inner_display(self, msg):
print("This is multilevel InnerInner class")
print(msg)

def inner_display(self, msg):
print("This is Inner class")
print(msg)

## ...


Let's see how to instantiate the multilevel inner class.

outer = Outer()

inner = outer.Inner()

## this is 'InnerInner' class instance
innerinner = inner.InnerInner() ## innerinner = Outer().Inner().InnerInner()

## let's call its method inner_display
innerinner.inner_display("Just Print It!")

This is multilevel InnerInner class
Just Print It!


## Conclusion

I hope you now understand the concept of inner classes. It's now time for you to experiment with nested classes. Happy Coding :)