C
Python/オブジェクト指向/Lesson 17

クラスの基礎

1時間·theory
このチャプター
1/3
Python

クラスの基礎

🎯 このlessonを読み終えたら

このlessonを読み終えると、以下の3つを自信を持って行えるようになります。

  • __init__ · self · インスタンスメソッドの基本
  • ✅ クラス変数とインスタンス変数の違い
  • ✅ マジックメソッド:__repr__ · __str__ · __eq__

学習目標をチェックリストとして持ち、すべてに答えられるようになったらlessonを閉じてください。

クラスの6つのコア概念 — コード + 実行結果

class = データ + 振る舞いをまとめた設計図。同じ形のオブジェクトを複数作りたいときに使います。

1. 最もシンプルなクラス

python
class Person:
    pass                       # とりあえず空のクラス

# オブジェクト生成
hong = Person()
lee = Person()

# 属性動的追加 (Pythonだけの特徴)
hong.name = "ホン・ギルドン"
hong.age = 28
print(hong.name)              # ホン・ギルドン

Person() を呼び出すとオブジェクトが生成されます。変数はそのオブジェクトを指します。

2. __init__ — コンストラクタ

python
class Person:
    def __init__(self, name, age):
        # オブジェクト作成時に自動呼び出し
        self.name = name           # self = 自分自身
        self.age = age

hong = Person("ホン・ギルドン", 28)            # __init__ 自動実行
print(hong.name, hong.age)            # ホン・ギルドン 28

self とは? = 「このメソッドを呼び出したオブジェクト自身」(Javaの this に相当)。すべてのメソッドの第1引数として必須です。

3. メソッド — オブジェクトの振る舞い

python
class Account:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount
        print(f"+{amount}円, 残高 {self.balance}円")
    def withdraw(self, amount):
        if amount > self.balance:
            print("残高不足!")
            return
        self.balance -= amount
        print(f"-{amount}円, 残高 {self.balance}円")

c = Account("ホン・ギルドン", 1000)
c.deposit(500)                # +500円, 残高 1500円
c.withdraw(2000)               # 残高不足!
c.withdraw(800)                # -800円, 残高 700円

メソッドを呼ぶ際は c.deposit(500) のように オブジェクト.メソッド(引数) と記述します — self は自動で渡されます。

4. __str__ — 出力フォーマット

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

    def __str__(self):
        return f"<人: {self.name}, {self.age}歳>"

hong = Person("ホン・ギルドン", 28)
print(hong)                  # <人: ホン・ギルドン, 28歳>

__str__ がなければ <__main__.Person object at 0x...> のような意味のない出力になります。必ず定義することを推奨します。

5. クラス変数 vs インスタンス変数

python
class Student:
    school = "コードマスター"           # クラス変数 (すべて共有)

    def __init__(self, name):
        self.name = name           # インスタンス変数 (オブジェクト別)

hong = Student("ホン・ギルドン")
lee = Student("イ・モンリョン")

print(hong.school, lee.school)            # コードマスター コードマスター
print(hong.name, lee.name)            # ホン・ギルドン イ・モンリョン

# クラス変数変更 — すべてに影響
Student.school = "スカイ"
print(hong.school, lee.school)            # スカイ スカイ

6. Javaとの比較 — より短い

python
# Python — 5行
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
java
// Java — 同一意味, 11行
class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() { return name; }
    public int getAge() { return age; }
}

一言まとめ

概念構文
定義class 名前:
コンストラクタdef __init__(self, ...):
自己参照self(すべてのメソッドの第1引数)
文字列出力def __str__(self):
オブジェクト生成obj = 名前(引数)
メソッド呼び出しobj.メソッド(引数)

ポイント:同じ形のオブジェクトを複数作るときに使います。self がまさにそのオブジェクトそのものです。

💻 クラスの基本例
# ============================================
# 📌 このコードがすること: クラスで「人」オブジェクトの設計図を作成し、使用します
# 📌 実生活の比喩: クラスは「たい焼きの型」です。
#    型(クラス)で複数のたい焼き(インスタンス)を作ることができます。
#    各たい焼きは同じ形ですが、中身(属性値)は異なる場合があります。
# ============================================

# 🔹 クラス定義: オブジェクトの属性と動作を設計します
class Person:
    # 🔹 クラス変数: すべてのインスタンスが共有する値 (一つのメモリに保存)
    species = "Homo sapiens"

    # 🔹 コンストラクタ(__init__): インスタンス生成時に自動呼び出し、初期値設定
    def __init__(self, name, age):
        # 🔹 インスタンス変数: 各インスタンスごとに独立して保存 (self.変数名)
        self.name = name  # 🔹 self = 生成されるインスタンス自身を指す
        self.age = age

    # 🔹 インスタンスメソッド: 最初の引数として必ずselfを受け取ります
    def greet(self):
        return f"こんにちは、{self.name}です。"  # 🔹 selfでインスタンス属性にアクセス

    def have_birthday(self):
        self.age += 1  # 🔹 インスタンス変数修正
        return f"{self.name}さん、{self.age}歳になりました!"

# 🔹 インスタンス生成: クラス名(引数) → __init__ 自動呼び出し
person1 = Person("チョルス", 25)  # 🔹 person1.name="チョルス", person1.age=25
person2 = Person("ヨニ", 23)  # 🔹 person2はperson1と完全に独立

# 🔹 メソッド呼び出し: インスタンス.メソッド() → self 自動伝達
print(person1.greet())        # ✅ 実行結果: こんにちは、チョルスです。
print(person1.have_birthday()) # ✅ 実行結果: チョルスさん、26歳になりました!

# 🔹 クラス変数アクセス: クラス名でも、インスタンスでもアクセス可能
print(Person.species)   # ✅ 実行結果: Homo sapiens (クラスで直接アクセス)
print(person1.species)  # ✅ 実行結果: Homo sapiens (インスタンスでアクセス、共有値)
# ❌ よくある間違い: person1.species = "new" とするとperson1だけのインスタンス変数が新しく生成されます

💡 重要ポイント

1. self はインスタンス自身を参照します
2. __init__ はコンストラクタ(自動呼び出し)
3. クラス変数とインスタンス変数を区別する

PythonのOOPはクラス(class)でオブジェクトを定義します。__init__ はコンストラクタ、self はインスタンス参照です。継承は class Child(Parent): で実装し、super() で親メソッドを呼び出します。@property でgetter/setterを実装し、@classmethod/@staticmethod でクラス/静的メソッドを定義します。多重継承とMRO(Method Resolution Order)もサポートされています。

🐍 実際に動かしてみよう — クラスの基礎

上記の概念を実際にコードで動かしてみましょう。値を変えながらどのように動くかを自分で確認するのが最も早い学習方法です。
✏️ Python 코드
📟 コンソール出力
▶ 実行ボタンを押してください
🐍 Pyodideで実際のPythonを実行 — 初回は読み込みに3〜5秒

🤖 AIへのリクエスト例

このlessonの概念を知っていれば、AIに具体的に指示することができます。漠然とした「直して」ではなく、語彙を持ったリクエスト — それがトークン節約の出発点です。

  • 「このPythonコードにクラスの基礎概念を適用して」
  • 「このコードにtype hint + pytestの単体テストを追加して」
  • 「クラスの基礎に関するPEP 8違反を確認して」

なぜこれがトークンを減らすのか

概念を知らないとAIの回答を受けても 「それは何ですか?」 と再度聞き直す必要があります。その「聞き直し」がトークンを消費します。概念を一度学んでおけば、会話が一度で完結します。

先に読むとよい概念: イテレーターとイテラブル
次のおすすめ: 継承
クラスの基礎 - Python