閉じる

【Python】インスタンス化入門|クラス生成・初期化・使い方をやさしく解説

Pythonでオブジェクト指向を学ぶ第一歩が「インスタンス化」です。

クラスという設計図から、実際に動かせる「もの」を作るプロセスのことを指します。

本記事では、クラス定義の基本から__init__メソッドによる初期化、インスタンス変数とクラス変数の違い、インスタンスの具体的な使い方まで、図解とサンプルコードを交えながら丁寧に解説します。

Python初心者の方でも、読み終わる頃には自分でクラスとインスタンスを設計・活用できるようになることを目指します。

Pythonのインスタンス化とは

インスタンスとクラスの基本用語

まずは言葉の整理から始めます。

Pythonのインスタンス化を理解するためには、クラスとインスタンスという2つの用語をしっかり押さえておく必要があります。

クラスとは、データとそのデータに対する操作(メソッド)をひとまとめにした「型」や「設計図」のようなものです。

例えば「犬」というクラスがあれば、名前や年齢などの情報と、吠える、走るといった動作を1つのまとまりとして記述します。

インスタンスとは、そのクラスから実際に作られた具体的な「もの」です。

「ポチ」という名前の犬、「タロウ」という名前の犬のように、クラスという共通の設計図をもとに、それぞれの具体的なデータを持つ実体がインスタンスです。

このように、クラスは抽象的な型、インスタンスはその型から生成された具体的なデータのまとまりだと理解してください。

インスタンス化(instance化)の意味

インスタンス化(instance化)とは、クラスという設計図から実際のインスタンスを作り出す処理のことです。

Pythonでは、クラス名にかっこを付けて呼び出すことでインスタンス化を行います。

例えば、次のように書きます。

Python
class Dog:
    pass  # まだ中身はないクラス

# Dogクラスのインスタンスを生成(インスタンス化)
pochi = Dog()
taro = Dog()

上のコードでは、Dog()という呼び出しがインスタンス化にあたります。

実行されると、Dogクラスから新しいインスタンスがメモリ上に作られ、その参照(アドレス)がpochitaroという変数に格納されます。

このように、インスタンス化はクラスを「使える状態にする」ための最初のステップです。

インスタンスとオブジェクトの違い

Pythonを学んでいると「インスタンス」と「オブジェクト」という2つの言葉が出てきます。

これらはとてもよく似た意味で使われていますが、ニュアンスの違いがあります。

一般的には、オブジェクトはもっと広い概念で、Pythonで値として扱えるすべてのものがオブジェクトです。

数値、文字列、リスト、関数、クラス、インスタンスなど、すべてがオブジェクトだと言えます。

一方でインスタンスは、あるクラスから生成された具体的なオブジェクトを指すことが多いです。

つまり、「Dogクラスのインスタンス」「listクラスのインスタンス」といった使い方をします。

実務的には、クラスからDog()のように生成したものを「インスタンス」と呼び、より広い意味で「Pythonのすべてはオブジェクト」という言い方をする、という程度に理解しておけば問題ありません。

Pythonクラスの定義と生成

クラス定義の基本構文

Pythonでクラスを定義する基本構文はとてもシンプルです。

最低限、classキーワードとクラス名、コロンの3つが必要です。

Python
class クラス名:
    # クラス本体(属性やメソッドをここに書く)
    ...

クラス名は先頭を大文字にするのがPythonの一般的な慣習です。

例えば、DogPersonUserAccountなどです。

具体例を見てみましょう。

Python
class Dog:
    # クラス変数(すべての犬に共通する情報)
    species = "canis familiaris"  # 学名

    # インスタンスメソッド
    def bark(self):
        print("わん!")

この例では、Dogクラスの中にspeciesというクラス変数と、barkというインスタンスメソッドを定義しています。

クラスからインスタンスを生成する手順

クラスが定義できたら、次はそのクラスからインスタンスを生成します。

Pythonでは、クラス名にかっこを付けて関数のように呼び出すだけです。

次のサンプルコードで、クラス定義からインスタンス生成、メソッド呼び出しまでの一連の流れを確認します。

Python
# Dogクラスの定義
class Dog:
    species = "canis familiaris"  # クラス変数

    def bark(self):
        # インスタンスメソッド
        print("わん!")

# Dogクラスからインスタンスを2つ生成
pochi = Dog()  # 1つ目のインスタンス
taro = Dog()   # 2つ目のインスタンス

# メソッド呼び出し
pochi.bark()  # pochiが吠える
taro.bark()   # taroが吠える

# クラス変数の参照
print(pochi.species)
print(taro.species)
実行結果
わん!
わん!
canis familiaris
canis familiaris

このように、同じクラスから複数のインスタンスを簡単に生成できます。

それぞれは別々のオブジェクトであり、後で学ぶインスタンス変数を使えば異なる状態を持たせることができます。

引数なしコンストラクタでインスタンス化する

コンストラクタとは、インスタンスを生成するときに最初に呼ばれる特別なメソッドのことです。

Pythonでは__init__メソッドがコンストラクタの役割を果たします。

ここでは、引数なしのコンストラクタを使ったインスタンス化を見てみましょう。

Python
class Counter:
    def __init__(self):
        # インスタンスごとにcountを0で初期化
        self.count = 0

    def increment(self):
        self.count += 1

    def show(self):
        print(f"現在のカウント: {self.count}")

# 引数なしでインスタンス化
c1 = Counter()
c2 = Counter()

c1.increment()
c1.increment()
c2.increment()

c1.show()
c2.show()
実行結果
現在のカウント: 2
現在のカウント: 1

クラス定義の中で__init__(self)とだけ書くと、インスタンス化の際に引数が不要なコンストラクタになります。

この場合、Counter()と丸かっこを付けて呼ぶだけでインスタンスを生成できます。

__init__による初期化とインスタンス変数

__init__メソッドの役割と書き方

__init__メソッドは、インスタンスが生成されるタイミングで自動的に呼び出されます。

主な役割はインスタンス変数の初期化です。

基本的な書き方は次のとおりです。

Python
class クラス名:
    def __init__(self, 引数1, 引数2, ...):
        # インスタンス変数の初期化処理
        self.変数名 = 値
        ...

具体例として、名前と年齢を持つPersonクラスを定義します。

Python
class Person:
    def __init__(self, name, age):
        # インスタンス変数に引数で受け取った値を代入
        self.name = name
        self.age = age

    def introduce(self):
        print(f"私は{self.name}です。{self.age}歳です。")

# インスタンス化のときに引数を渡す
p1 = Person("太郎", 20)
p2 = Person("花子", 25)

p1.introduce()
p2.introduce()
実行結果
私は太郎です。20歳です。
私は花子です。25歳です。

このように__init__を使うことで、インスタンスが生成された瞬間に必要な値を設定し、使いやすい状態にしておくことができます。

selfとは何かとその使い方

Pythonのクラス定義では、インスタンスメソッドや__init__メソッドの第1引数としてselfを書くのがルールです。

これはそのメソッドが呼び出されたインスタンス自身を指します。

具体的には、メソッドを呼び出すときの見た目と、実際にPython内部で呼ばれている形を対応づけると理解しやすくなります。

Python
class Sample:
    def show_id(self):
        print(id(self))  # selfが指すオブジェクトのIDを表示

s1 = Sample()
s2 = Sample()

# 見た目
s1.show_id()
s2.show_id()

# 実際にPythonが内部で行っている呼び出しイメージ
Sample.show_id(s1)
Sample.show_id(s2)
実行結果
140503238166960
140503238167056

このように、s1.show_id()と書くと、Python内部ではSample.show_id(s1)という形で関数が呼ばれており、その第1引数がselfになります。

selfという名前は慣習であり、実は任意の名前に変えることもできますが、読みやすさのために必ずselfを使うことをおすすめします。

インスタンス変数とクラス変数の違い

クラスの中で定義する変数には、大きく分けてインスタンス変数クラス変数の2種類があります。

それぞれの違いをしっかり理解することが、インスタンス化を正しく扱うための鍵です。

違いを表にまとめます。

種類定義場所共有範囲典型的な用途
インスタンス変数__init__などメソッド内でself.xxxとして定義インスタンスごとに別々個々のオブジェクト固有の情報(名前など)
クラス変数クラスブロック直下で定義クラスのすべてのインスタンスで共有全インスタンス共通の情報(定数など)

具体例を見てみましょう。

Python
class Dog:
    # クラス変数(全ての犬に共通)
    species = "canis familiaris"

    def __init__(self, name):
        # インスタンス変数(犬ごとに異なる)
        self.name = name

# インスタンスを2つ生成
pochi = Dog("ポチ")
taro = Dog("タロウ")

# インスタンス変数の値(それぞれ異なる)
print(pochi.name)  # ポチ
print(taro.name)   # タロウ

# クラス変数の値(どちらも同じ)
print(pochi.species)  # canis familiaris
print(taro.species)   # canis familiaris
実行結果
ポチ
タロウ
canis familiaris
canis familiaris

このように、インスタンス変数はself.nameのようにselfを通じてアクセスし、クラス変数はクラス名からDog.speciesとしてもアクセスできます。

デフォルト引数付きのインスタンス化

__init__メソッドの引数には、通常の関数と同じようにデフォルト引数を指定できます。

これにより、すべての引数を毎回指定しなくても、よく使う値を省略できて便利です。

Python
class User:
    def __init__(self, name, is_active=True):
        self.name = name
        self.is_active = is_active

    def show_status(self):
        status = "有効" if self.is_active else "無効"
        print(f"{self.name} さんのアカウントは {status} です。")

# is_activeを省略(デフォルトのTrueが使われる)
u1 = User("山田")

# is_activeを明示的に指定
u2 = User("佐藤", is_active=False)

u1.show_status()
u2.show_status()
実行結果
山田 さんのアカウントは 有効 です。
佐藤 さんのアカウントは 無効 です。

このように、__init__(self, name, is_active=True)と書くことで、is_activeを省略した場合にはTrueが自動的に使われます。

引数の数が増えてきたときは、デフォルト引数やキーワード引数を組み合わせることで、インスタンス化をわかりやすく保つことができます。

実例で学ぶクラスとインスタンスの初期化

ここまで学んだ内容をまとめるために、少し実用的なサンプルとして「銀行口座」を表すクラスを作ってみます。

Python
class BankAccount:
    # クラス変数(全口座共通の銀行名)
    bank_name = "Python銀行"

    def __init__(self, owner, initial_balance=0):
        # インスタンス変数
        self.owner = owner            # 口座名義
        self.balance = initial_balance  # 残高(デフォルト0)

    def deposit(self, amount):
        self.balance += amount
        print(f"{amount}円を預け入れました。")

    def withdraw(self, amount):
        if amount > self.balance:
            print("残高不足です。")
            return
        self.balance -= amount
        print(f"{amount}円を引き出しました。")

    def show_balance(self):
        print(f"{self.owner} さんの残高: {self.balance}円 ({self.bank_name})")

# インスタンス生成
account1 = BankAccount("田中", initial_balance=1000)
account2 = BankAccount("鈴木")  # 初期残高省略 → 0円

account1.deposit(500)
account1.withdraw(300)
account1.show_balance()

account2.deposit(2000)
account2.show_balance()
実行結果
500円を預け入れました。
300円を引き出しました。
田中 さんの残高: 1200円 (Python銀行)
2000円を預け入れました。
鈴木 さんの残高: 2000円 (Python銀行)

この例では、__init__メソッドを使って口座名義と初期残高を設定し、インスタンスごとに異なる状態を持っています。

一方で、銀行名はクラス変数bank_nameとして全インスタンスで共通になっています。

インスタンスの使い方と実践パターン

インスタンスメソッドの呼び出し方

インスタンスメソッドは、インスタンスを通じて呼び出すのが基本です。

先ほどのBankAccountクラスを例にすると、次のようになります。

Python
class Greeter:
    def __init__(self, name):
        self.name = name

    def greet(self):
        print(f"こんにちは、{self.name}さん!")

# インスタンス生成
g = Greeter("佐藤")

# インスタンスメソッドの呼び出し
g.greet()
実行結果
こんにちは、佐藤さん!

このg.greet()という書き方が、インスタンスメソッドの標準的な呼び出し方です。

内部的にはGreeter.greet(g)と同じ意味になりますが、通常はこのような直接的な呼び方はしません。

プロパティ(属性)の参照と更新

インスタンスが持つデータ(インスタンス変数)は、ドット演算子.を使って参照・更新できます。

次のコードで、属性の参照と更新の流れを確認します。

Python
class User:
    def __init__(self, name, age):
        self.name = name  # インスタンス変数
        self.age = age

# インスタンス生成
user = User("田中", 30)

# 属性の参照
print(user.name)  # 田中
print(user.age)   # 30

# 属性の更新
user.age = 31
print(user.age)   # 31

# 新しい属性を後から追加することも可能(推奨はしない)
user.email = "taro@example.com"
print(user.email)
実行結果
田中
30
31
taro@example.com

Pythonでは、インスタンスに対して後から新しい属性を追加することもできますが、コードの見通しが悪くなりやすいので、基本的には必要な属性は__init__で定義しておくことをおすすめします。

より高度な方法として@propertyデコレータを使うと、メソッド呼び出しを属性アクセスのように見せることもできますが、本記事ではインスタンス化入門に焦点を当てるため、詳細な説明は割愛します。

インスタンス化のよくあるエラーと対処法

インスタンス化の際には、いくつか典型的なエラーが発生しがちです。

代表的なものと、その対処法を見てみましょう。

引数の数が合わないエラー

TypeError: __init__() missing … required positional arguments というエラーは、インスタンス化のときに必要な引数を渡していない場合に発生します。

Python
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 引数が足りない例
p = Person("太郎")  # ageが指定されていない
実行結果
TypeError: Person.__init__() missing 1 required positional argument: 'age'

この場合は、ageを指定するか、もしくは__init__側でデフォルト引数を設定することで解決できます。

Python
class Person:
    def __init__(self, name, age=20):  # デフォルト値を設定
        self.name = name
        self.age = age

selfを忘れるエラー

TypeError: … takes 1 positional argument but 2 were given というエラーは、メソッド定義でselfを付け忘れたときなどに出ることがあります。

Python
class Sample:
    # selfを付け忘れた誤った定義
    def show():
        print("Hello")

s = Sample()
s.show()  # ここでエラー
実行結果
TypeError: Sample.show() takes 0 positional arguments but 1 was given

メソッド定義では、必ず第1引数にselfを書くようにしてください。

Python
class Sample:
    def show(self):  # 正しい定義
        print("Hello")

クラスを呼ばずにそのまま使ってしまうミス

クラス名に丸かっこを付け忘れて、インスタンスではなくクラス自体を変数に代入してしまうミスもよくあります。

Python
class Counter:
    def __init__(self):
        self.count = 0

# 誤り: 丸かっこがない
c = Counter  # これはクラスへの参照であってインスタンスではない

# 後でエラーになる可能性がある
# c.count などにアクセスしようとすると AttributeError となる

常にインスタンス化するときはクラス名()と丸かっこを書くことを意識してください。

インスタンスを使ったシンプルなアプリ例

最後に、インスタンス化を活用したシンプルなアプリ例として、「ToDoリスト」をクラスで表現してみます。

ここでは、1つのタスクを表すTaskクラスと、タスクをまとめて管理するTodoListクラスを設計します。

Python
class Task:
    def __init__(self, title):
        self.title = title    # タスク名
        self.is_done = False  # 完了フラグ

    def toggle(self):
        # 完了/未完了を切り替え
        self.is_done = not self.is_done

    def __str__(self):
        # print時の表示形式を定義
        status = "✔" if self.is_done else " "
        return f"[{status}] {self.title}"


class TodoList:
    def __init__(self):
        self.tasks = []  # Taskインスタンスを格納するリスト

    def add_task(self, title):
        task = Task(title)
        self.tasks.append(task)
        print(f"タスクを追加しました: {title}")

    def complete_task(self, index):
        if 0 <= index < len(self.tasks):
            self.tasks[index].toggle()
            print(f"タスクの完了状態を切り替えました: {self.tasks[index].title}")
        else:
            print("指定された番号のタスクは存在しません。")

    def show_tasks(self):
        if not self.tasks:
            print("タスクはありません。")
            return
        print("=== タスクリスト ===")
        for i, task in enumerate(self.tasks):
            print(f"{i}: {task}")

# TodoListのインスタンスを生成
todo = TodoList()

# タスク追加
todo.add_task("Pythonの勉強をする")
todo.add_task("メールを確認する")
todo.add_task("買い物に行く")

# タスク一覧表示
todo.show_tasks()

# 1番目のタスクを完了に切り替え
todo.complete_task(1)

# 再度タスク一覧表示
todo.show_tasks()
実行結果
タスクを追加しました: Pythonの勉強をする
タスクを追加しました: メールを確認する
タスクを追加しました: 買い物に行く
=== タスクリスト ===
0: [ ] Pythonの勉強をする
1: [ ] メールを確認する
2: [ ] 買い物に行く
タスクの完了状態を切り替えました: メールを確認する
=== タスクリスト ===
0: [ ] Pythonの勉強をする
1: [✔] メールを確認する
2: [ ] 買い物に行く

このサンプルでは、タスク1件を表すインスタンスTaskと、それらをまとめて扱うTodoListインスタンスを使って、簡単なアプリのような構造を作っています。

インスタンス化を使うことで、関連するデータと処理をまとめて扱えるようになり、プログラム全体の見通しが良くなります。

まとめ

Pythonのインスタンス化は、クラスという設計図から具体的なオブジェクトを生み出す重要な仕組みです。

本記事では、クラス定義の基本、__init__メソッドとselfの意味、インスタンス変数とクラス変数の違い、デフォルト引数を使った柔軟な初期化方法、そしてインスタンスを活用した簡単なアプリ例までを解説しました。

インスタンス化を理解すると、データと処理を整理して表現できるようになり、プログラムの再利用性や拡張性が大きく向上します。

ぜひ、自分の身近なもの(本、ユーザー、商品など)をクラスとインスタンスで表現する練習をしながら、理解を深めていってください。

クラスとオブジェクト指向

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!