Python 速習チュートリアル

Python のインナークラス (Inner Classes)

1. Pythonのインナークラス

インナークラス(Inner Class / 内部クラス)とは、別のクラスの中で定義されたクラスのことです。インナークラスは、外部クラスのプロパティやメソッドにアクセスすることが可能です。

インナークラスは、特定の場所でしか使用されないクラスをグループ化するのに非常に有効で、コードの構造をより論理的かつ綺麗に整理(構造化)することができます。

1.1 インナークラスの作成例

基本的なインナークラスの定義方法を見てみましょう。

class Outer:
  def __init__(self):
    self.name = "Outer Class (外部クラス)"

  class Inner:
    def __init__(self):
      self.name = "Inner Class (内部クラス)"

    def display(self):
      print("これはインナークラスです")

outer = Outer()
print(outer.name)

2. 外部からのインナークラスへのアクセス

インナークラスのインスタンスを作成するには、まず外部クラス(Outer class)のオブジェクトを作成し、そのオブジェクトを介してインナークラスのオブジェクトを作成する必要があります。

2.1 インナークラスのオブジェクト生成

外部から内部へ階層を辿ってアクセスする手順は以下の通りです。

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

  class Inner:
    def __init__(self):
      self.name = "Inner"

    def display(self):
      print("インナークラスからこんにちは")

# 1. まず外部クラスをインスタンス化
outer = Outer()
# 2. 外部クラスのインスタンスを使用してインナークラスをインスタンス化
inner = outer.Inner()
inner.display()

3. インナークラスから外部クラスへのアクセス

Pythonのインナークラスは、デフォルトでは外部クラスのインスタンスに直接アクセスできるわけではありません。
インナークラスから外部クラスのデータを利用したい場合は、外部クラスのインスタンスを引数(パラメータ)として渡す設計にする必要があります。

3.1 外部クラスのインスタンスを渡す例

class Outer:
  def __init__(self):
    self.name = "エミル"

  class Inner:
    def __init__(self, outer):
      # 外部クラスの参照を保持
      self.outer = outer

    def display(self):
      print(f"外部クラスの名前: {self.outer.name}")

outer = Outer()
# インナークラスの初期化時に外部インスタンス(outer)を渡す
inner = outer.Inner(outer)
inner.display()

4. 実用的なユースケース

インナークラスは、外部クラスのコンテキスト内でのみ意味を持つ「ヘルパー(Helper)クラス」を作成するのに適しています。

4.1 車(Car)とエンジン(Engine)の関係

車という大きな概念の中に、その一部であるエンジンをインナークラスとして定義する例です。

class Car:
  def __init__(self, brand, model):
    self.brand = brand
    self.model = model
    # インスタンス生成時にEngineオブジェクトも作成
    self.engine = self.Engine()

  class Engine:
    def __init__(self):
      self.status = "Off (停止)"

    def start(self):
      self.status = "Running (稼働中)"
      print("エンジンが始動しました")

    def stop(self):
      self.status = "Off (停止)"
      print("エンジンが停止しました")

  def drive(self):
    if self.engine.status == "Running (稼働中)":
      print(f"{self.brand} {self.model} を運転しています")
    else:
      print("先にエンジンを始動してください!")

car = Car("トヨタ", "カローラ")
car.drive()
car.engine.start()
car.drive()

5. 複数のインナークラス

1つのクラスの中に、複数の異なるインナークラスを定義することも可能です。これにより、複雑なオブジェクトを構成要素ごとに細かく分割して管理できます。

5.1 コンピュータ構成の多重インナークラス例

class Computer:
  def __init__(self):
    self.cpu = self.CPU()
    self.ram = self.RAM()

  class CPU:
    def process(self):
      print("データを処理しています...")

  class RAM:
    def store(self):
      print("データをメモリに保存しています...")

computer = Computer()
computer.cpu.process()
computer.ram.store()