In this tutorial we will explore what inner (nested) classes are and how to use them in Python.

Table of contents


What are inner (nested) classes in Python?

You are probably already familiar with object oriented programming and the concept of a Python class.

Now, we extend this concept to think of inner (nested) classes just as you think of nested functions:


def outer_function():
    def inner_function():
        print("Hello!")
    return inner_function()

Just as you can create a function within a function, in Python, you can create a class inside of a class. Sounds quite functional right?


When and why should you use inner (nested) classes?

Inner (nested) classes is not something you will see often unless you are at an intermediate/advanced level and actively work with object oriented programming in Python in several projects.

However it is still an important concept to learn which really helps with thinking of how to structure your code. It will definitely help you become a better programmer and most importantly help make your code more friendly and more readable for other programmers working with you on the same projects.

Let’s dive into it! Why inner (nested) classes?

  1. Write cleaner code and make it more object oriented. Inner (nested) classes allow to create more understandable code which is easy to read and knowledge transfer. It is especially useful if two classes are related, and now you can have one class under the umbrella of another class.
  2. Assemble code from different Python files where classes are defined and stored. This way each person on a project can easily manage the class they are working on and allow other team members to use it by just importing it from another file in the directory.

While the above explanations should be comprehensive enough for majority of readers, it is much easier to get a grasp of the concept by following a few examples.

Let’s take a look!


Examples of inner (nested) classes in Python

Inner classes in Python can be created in a few simple steps.


Step 1: Create an outer class

Let’s start with a simple Computer() class that has a name “PC001”:


class Computer():
    def __init__(self):
        self.name = "PC001"

if __name__ == "__main__":
    my_comp = Computer()
    print(my_comp.name)

If we run the above code, all we do is create an instance of Computer() class and print out its name which I defined inside of the class:

PC001

Each computer has multiple parts inside of it. What we will do is create inner classes which will relate to parts of the Computer() class.


Step 2: Create inner classes

For this example, we will consider a computer with two main components: OS and CPU.


class OS():
    def system():
        return "Windows 10"

class CPU():
    def make():
        return "Intel"
    def model():
        return "Core-i7"

Now what we want to do is have these two classes as inner classes in the Computer() class:


class Computer():
    def __init__(self):
        self.name = "PC001"
        self.os = self.OS()
        self.cpu = self.CPU()
    
    class OS():
        def system(self):
            return "Windows 10"

    class CPU():
        def make(self):
            return "Intel"
        def model(self):
            return "Core-i7"

if __name__ == "__main__":
    my_comp = Computer()
    my_os = my_comp.os
    my_cpu = my_comp.cpu
    print(my_comp.name)
    print(my_os.system())
    print(my_cpu.make())
    print(my_cpu.model())

And you should get:

PC001
Windows 10
Intel
Core-i7

This way it is much more convenient to read through the code, call relevant methods, and worked with a larger class since now each inner class can be maintained separately without affecting the outer class as long as it returns the expected output.


Step 3: Hide inner classes to other files in the directory

Everything looks great so far. We created inner classes in Python, the code is working and we made it more object oriented. But there is one more thing to it!

Let’s assume your team consists of three software engineers: John, Maria, and Sam. Each software engineer works on the class assigned to them.

For example:

  • John works on Computer() class
  • Maria works on OS() class
  • Sam works on CPU() class

Here all of our code is in one single file (let’s call it main.py) which will require all three of them work within the same file basically and make any changes they need, because your directory looks like this:

└─── ComputerProject
     └─── main.py

While this code is short and it can seem efficient, in reality it is not. As more people work on it, it creates more confusion as more changes to the code are added.

But how can we solve it? We can!

What we are going to do is create multiple Python files in the same directory each containing a single class. For example, something like this:

└─── ComputerProject
     └─── main.py
     └─── os_work.py
     └─── cpu_work.py

and we move relevant code to the new files.

Now, your os_work.py file should contain:


class OS():
    def system(self):
        return "Windows 10"

and your cpu_work.py file should contain:


class CPU():
    def make(self):
        return "Intel"
    def model(self):
        return "Core-i7"

Since now each inner class is defined in its own file, we don’t need to define it inside of the Computer() class, rather we can import the defined classes from the files, and to the self assignment.

Your main.py should look like this:


from os_work import OS
from cpu_work import CPU

class Computer():
    def __init__(self):
        self.name = "PC001"
        self.os = OS()
        self.cpu = CPU()

if __name__ == "__main__":
    my_comp = Computer()
    my_os = my_comp.os
    my_cpu = my_comp.cpu
    print(my_comp.name)
    print(my_os.system())
    print(my_cpu.make())
    print(my_cpu.model())

And we should get the same output as in Step 2:

PC001
Windows 10
Intel
Core-i7

Notice how the restructured code is much easier to read and also much easier to work with.

Back to our example, each software engineer will work in the file related to the class they are working on and can freely make any necessary changes without touching files with other classes.


Conclusion

In this tutorial we explored inner (nested) classes in Python, what they are, why and how to use them to create more structured code.

I also encourage you to check out my other posts on Python Programming.

Feel free to leave comments below if you have any questions or have suggestions for some edits.