Python Inner Classes

Ka Kavitha V Updated 03 Oct 2026
5 min read

Inner Classes

An inner class (also called a nested class) is a class defined inside another class. It is used when a class is closely tied to another class and has little meaning on its own — for example, a Battery that only exists as part of a Laptop, or Settings that belong to a Profile.

Inner classes help you:

  • Organize related code — the helper class lives right next to the class that uses it
  • Improve readability — the structure of the code mirrors the structure of the real-world object
  • Limit the scope of helper classes — the inner class is accessed through the outer class, so it does not clutter the module's top-level names

Defining an Inner Class

An inner class is declared inside the outer class's body, at the same indentation level as its methods.

Example: A Basic Inner Class

class Container:
    def __init__(self):
        self.title = "Main Container"

    class Item:
        def show(self):
            print("This is an item inside the container")

box = Container()
print(box.title)

Expected output:

Main Container
  • Container is the outer class.
  • Item is the inner class, defined inside Container's body.
  • Creating a Container object does not automatically create an Item object. The inner class is only a definition until you create an instance of it.

Creating Objects of an Inner Class

An inner class is an attribute of the outer class, so you reach it with dot notation. There are two ways to access it.

Through an Instance of the Outer Class

class Library:
    def __init__(self):
        self.name = "City Library"

    class Book:
        def info(self):
            print("Book belongs to the library")

library = Library()
book = library.Book()
book.info()

Expected output:

Book belongs to the library

library.Book looks up the Book class through the library object, and the parentheses create a new Book object.

Through the Outer Class Directly

You do not need an outer object to create an inner object. You can access the inner class through the outer class name:

book = Library.Book()
book.info()

Expected output:

Book belongs to the library

Both forms create the same kind of object, because the inner class belongs to the outer class, not to any particular outer object.

Accessing Outer Class Data From an Inner Class

Unlike in some other languages (such as Java), a Python inner class object has no automatic connection to an outer class object. Being defined inside another class only affects where the class is found, not what its objects can access.

To use the outer object's data, pass the outer object explicitly to the inner class.

Example: Passing the Outer Object

class Profile:
    def __init__(self):
        self.username = "guest_user"

    class Settings:
        def __init__(self, profile):
            self.profile = profile

        def display(self):
            print("Profile username:", self.profile.username)

profile = Profile()
settings = profile.Settings(profile)
settings.display()

Expected output:

Profile username: guest_user

How it works:

  1. profile is created with username = "guest_user".
  2. profile.Settings(profile) creates a Settings object and passes the profile object to its __init__().
  3. The Settings object stores that reference in self.profile.
  4. display() reads self.profile.username — the outer object's data.

Without the explicit reference, Settings would have no way to know which Profile it belongs to.

Practical Use Case: Modeling Components

Inner classes are useful for modeling components that belong to a larger object. Often, the outer class creates its inner objects in its own __init__().

Example: A Laptop With a Battery

class Laptop:
    def __init__(self, brand):
        self.brand = brand
        self.battery = self.Battery()

    class Battery:
        def __init__(self):
            self.level = 0

        def charge(self):
            self.level = 100
            print("Battery fully charged")

        def drain(self):
            self.level = 10
            print("Battery low")

    def use(self):
        if self.battery.level > 20:
            print(f"Using the {self.brand} laptop")
        else:
            print("Please charge the battery first")

lap = Laptop("Dell")
lap.use()
lap.battery.charge()
lap.use()

Expected output:

Please charge the battery first
Battery fully charged
Using the Dell laptop

How it works:

  1. Laptop("Dell") runs Laptop.__init__(), which stores the brand and creates a Battery object with self.Battery(). The new battery starts at level 0.
  2. The first lap.use() checks self.battery.level. Because 0 is not greater than 20, it asks for a charge.
  3. lap.battery.charge() calls the Battery object's method, setting its level to 100.
  4. The second lap.use() now sees a level of 100 and uses the laptop.

Each Laptop object gets its own Battery object, so charging one laptop does not affect another. This kind of relationship — a laptop has a battery — is called composition.

Using Multiple Inner Classes

An outer class can contain several inner classes, each representing a different component.

Example: A Smartphone With a Camera and a Speaker

class Smartphone:
    def __init__(self):
        self.camera = self.Camera()
        self.speaker = self.Speaker()

    class Camera:
        def capture(self):
            print("Photo captured")

    class Speaker:
        def play_sound(self):
            print("Playing sound")

phone = Smartphone()
phone.camera.capture()
phone.speaker.play_sound()

Expected output:

Photo captured
Playing sound

phone.camera and phone.speaker are separate objects created during the smartphone's initialization. Each component handles its own responsibility, and the Smartphone class brings them together.

When to Use Inner Classes

Inner classes are a good fit when:

  • The inner class is only meaningful as part of the outer class.
  • You want to group a small helper class with the class that uses it.
  • You want to signal to readers that the classes belong together.

Prefer separate, top-level classes when:

  • The class is useful on its own or is used by several other classes.
  • The inner class is large or complex.
  • Other modules need to import and use the class directly.

Inner classes are used less often in Python than in some other languages. Many Python developers prefer separate classes combined through composition (self.battery = Battery()), which is equally clear and easier to reuse.

Common Mistakes

MistakeProblem
Expecting the inner object to access outer attributes automaticallyAttributeError; pass the outer object explicitly
Assuming creating the outer object creates inner objectsInner objects are created only when you call the inner class
Calling Battery() inside the outer class without self. or the class nameNameError; use self.Battery() or Laptop.Battery()
Nesting classes deeplyMakes code hard to read and test
  • Python Classes and Objects — defining and instantiating classes
  • Python __init__() Method — creating component objects during initialization
  • Python Inheritance — the "is-a" relationship, in contrast to composition's "has-a"
  • Python Encapsulation — grouping related data and behavior

0 Comments

Reviewed before they appear

No comments yet.

Python
Ask about this post
AI Ask about this post

Ask questions about Python Inner Classes and get answers drawn from it.

Signed-in readers only.