Python: クラスとオブジェクト
最終更新:2026-09-22
ここまでのいくつかのレッスンでは、関数を使ってコードを整理する——「何をするか」に焦点を当てた「手続き型」アプローチをとってきました。オブジェクト指向プログラミング(OOP)は「誰がするか」に焦点を当て、データとそのデータを操作するメソッドをオブジェクトにパッケージ化します。Python のすべてはオブジェクトです。OOP を理解することは重要な前進です。
1. クラスとオブジェクトとは
クラスは設計図であり、オブジェクトはその設計図から作成された具体的なインスタンスです。
# 「Dog」クラスを定義 — 設計図
class Dog:
pass
# 設計図から具体的な「Dog」オブジェクトを作成
my_dog = Dog()
print(type(my_dog)) # <class '__main__.Dog'>
print(my_dog) # <__main__.Dog object at 0x...>
「犬」という品種が概念(クラス)であるのと同様に、あなたが飼っている特定の犬のワンちゃんはインスタンス(オブジェクト)です。1 つのクラスから無数のオブジェクトを作成できます。
2. __init__:コンストラクタメソッド
オブジェクトを作成するとき、__init__ メソッドが自動的に呼び出され、オブジェクトの属性を初期化します:
class Dog:
"""Dog class"""
def __init__(self, name, age):
self.name = name # インスタンス属性
self.age = age
# オブジェクト作成時にパラメータを渡す
dog1 = Dog("Wangcai", 3)
dog2 = Dog("Xiaobai", 1)
print(dog1.name) # Wangcai
print(dog2.name) # Xiaobai
print(dog1.age) # 3
__init__ はコンストラクタではありません——オブジェクトはそれが呼び出される前に作成されます。実際のコンストラクタは __new__ ですが、それに触れる必要はほとんどありません。__init__ の最初のパラメータは常に self で、現在のオブジェクトインスタンスを表します。
▶ サンプル:Student クラスの定義(難易度 ⭐)
▶ 試してみよう出力:
# 函数定义成功
3. メソッド:オブジェクトの振る舞い
クラス内で定義された関数をメソッドと呼びます。最初のパラメータは常に self で、メソッドを呼び出すオブジェクト自体を表します。
class Calculator:
"""簡易電卓"""
def __init__(self):
self.result = 0
def add(self, value):
self.result += value
return self
def subtract(self, value):
self.result -= value
return self
def show(self):
return self.result
calc = Calculator()
calc.add(10)
calc.subtract(3)
print(calc.show()) # 7
# メソッドチェーン — 各メソッドが self を返す
result = Calculator().add(10).subtract(3).add(5).show()
print(result) # 12
self を返すメソッドはチェーンできます。多くの Python ライブラリ(pandas など)がこのパターンを広く使用しています。
4. インスタンス属性 vs クラス属性
属性はインスタンス(各オブジェクトに固有)またはクラス(すべてのオブジェクトで共有)に定義できます:
class Student:
# クラス属性 — すべての学生で共有
school = "First High School"
total_count = 0
def __init__(self, name):
# インスタンス属性 — 各学生に固有
self.name = name
Student.total_count += 1
s1 = Student("Zhang San")
s2 = Student("Li Si")
# クラス属性はクラス名でアクセス
print(Student.school) # First High School
print(Student.total_count) # 2
# インスタンスからもアクセス可能(同名のインスタンス属性がない場合)
print(s1.school) # First High School
print(s2.school) # First High School
# クラス属性の変更はすべてのインスタンスに影響
Student.school = "Second High School"
print(s1.school) # Second High School
▶ サンプル:銀行口座(難易度 ⭐⭐)
▶ 試してみよう出力:
# 函数定义成功
5. よくあるユースケース
(3) ▶ サンプル:学生成績管理クラス (難易度 ⭐⭐)
▶ 試してみよう出力:
Student: Alice (001)
Chinese: 85 (Pass)
Math: 72 (Pass)
English: 90 (Pass)
Average: 82.3
Student: Bob (002)
Chinese: 55 (Fail)
Math: 48 (Fail)
Average: 51.5
Total students: 2
5. よくあるユースケース
- データモデリング:現実世界のエンティティをコードにマッピング——ユーザー、注文、製品はすべてクラスで表現
- 状態管理:オブジェクトが状態(属性)を保持し、メソッドがその状態を操作——例:ゲームキャラクター、ショッピングカート
- コード整理:関連するデータと関数を一緒にパッケージ化。分散した関数よりもクリーン
- フレームワーク拡張:Django のモデル、Flask のアプリケーション、GUI コンポーネントはすべてクラスで実装
❓ よくある質問
self を最初のパラメータとして持ちます。関数は独立して存在できます。メソッドはオブジェクトまたはクラスを介して呼び出す必要があります。本質的に、メソッドは Python が呼び出し元を最初の引数として自動的に渡す関数です。self を他の名前に変更できますか?self は Python コミュニティの固いルールです。名前を変更しても機能はしますが、コードを読む人(将来の自分を含む)が違和感を持ちます。常に self を使用してください。📖 まとめ
- クラスは設計図。オブジェクトはそれから作成された具体的なインスタンス
__init__は初期化メソッド。オブジェクト作成時に自動呼び出し- メソッドの最初のパラメータは
selfで、現在のオブジェクトを表す - インスタンス属性は各オブジェクトに固有。クラス属性はすべてのオブジェクトで共有
- クラスはデータとそれを操作するメソッドを一緒にパッケージ化
📝 練習問題
-
初級(難易度 ⭐):
Carクラスを定義し、brand、color、speed属性を持たせます。速度を上げるaccelerate(value)メソッドと現在の速度を表示するshow_speed()メソッドを含めてください。 -
中級(難易度 ⭐⭐):
Studentクラスを定義します。クラス属性で学生の総数を追跡し、インスタンス属性で各学生の名前とスコアを記録します。英字グレード(A、B、C、D)を返すget_grade()メソッドを実装してください。 -
上級(難易度 ⭐⭐⭐):
LibraryクラスとBookクラスを定義します。Bookはタイトル、著者、貸出状態を持ちます。Libraryは 4 つのメソッドadd_book(book)、borrow(title)、return_book(title)、show_books()を持ちます。