Python環境を起動中... 初回のみ数秒かかります
Lesson 13 / 20

クラスの基礎

このレッスンで学ぶこと

  • クラスを定義し、インスタンスを作成できる
  • __init__self の役割を理解できる
  • インスタンス変数とクラス変数の違いを説明できる
  • メソッドを追加して、データと処理をまとめられる

1. クラスとは何か

クラスは「データ(属性)」と「処理(メソッド)」をひとまとめにした設計図です。 患者情報を例にすると、「名前・年齢・体重・身長」がデータ、「BMIを計算する」「情報を表示する」が処理です。

いつクラスを使うのか:「同じ種類のもの(患者・検査結果・モデルなど)を複数扱い、それぞれが独自のデータと処理を持つ」場合に使います。 関数が「1つの処理をまとめる」のに対し、クラスはデータと複数の処理をセットで管理するための仕組みです。

class クラス名: で定義し、クラス名() で「インスタンス(実体)」を作ります。

sample_1.py
Ctrl+Enter
出力

💡 クラス・インスタンス・インスタンス化のイメージ:

  • クラス = 設計図(例:「患者カルテの書式」)
  • インスタンス = 設計図から作った実物(例:「田中さんのカルテ1枚」「山田さんのカルテ1枚」)
  • インスタンス化 = 設計図から実物を作る操作(Patient("田中太郎", 45) と書くこと)
# Patient クラスは「患者カルテの書式(設計図)」
# p1, p2 はその書式から作られた「別々のカルテ(インスタンス)」
p1 = Patient("田中太郎", 45, 70, 1.75)   # 田中さんのカルテを1枚作成(インスタンス化)
p2 = Patient("山田花子", 62, 58, 1.62)   # 山田さんのカルテを1枚作成

# p1 と p2 は同じ設計図(Patientクラス)から作られているが
# name・age・weight・height はそれぞれ別の値を持つ独立した存在

💡 self とは?

メソッドの第1引数は慣習的に self と名付けます(他の名前でも動きますが、全員 self を使います)。self は「メソッドを呼び出したインスタンス自身」を指します。

# この2行は内部的に同じ意味
p1.show_info()               # ← 通常の書き方(Pythonが self=p1 を自動で渡す)
Patient.show_info(p1)        # ← Pythonが内部でやっていること

# メソッドの中では...
# self.name  →  p1.name("田中太郎")
# self.age   →  p1.age(45)

複数のインスタンスが同じメソッドを使うとき、self がないと「どのインスタンスのデータか」を区別できません。self は「私(このインスタンス)のデータ」という意味のラベルです。

💡 __init__(self, name, age) の引数の意味:

Patient("田中太郎", 45) と書いたとき、Pythonは次の流れで動きます:

# ① Patient("田中太郎", 45) を呼び出す
# ② Pythonが自動で __init__(self=p1, name="田中太郎", age=45) を実行
#    ↑ self には「今作ったばかりのインスタンス」が自動で渡される
#    ↑ name, age には呼び出し時に渡した値が入る
# ③ __init__ 内で self.name = "田中太郎" などが保存される

p1 = Patient("田中太郎", 45)
# p1.name → "田中太郎"
# p1.age  → 45

つまり self は「今まさに作っているインスタンス」を指し、__init__ はインスタンスが生まれた瞬間に呼ばれる「初期設定メソッド」です。

2. クラス変数とインスタンス変数

インスタンス変数self.xxx)はインスタンスごとに異なる値。 クラス変数はクラス全体で共有する値です。カウンタや定数として使います。

sample_2.py
Ctrl+Enter
出力

💡 クラス変数を変更するときPatient.patient_count += 1 のようにクラス名で操作します。self.patient_count += 1 とすると、そのインスタンスだけのインスタンス変数が作られてしまいます。

3. 複数のメソッドを持つクラス

クラスにメソッドを追加することで、関連する処理をまとめられます。 医療データ管理クラスを例に見てみましょう。

sample_3.py
Ctrl+Enter
出力

4. クラスと PyTorch の関係

📌 AI知識がある方向け・スキップ可:PyTorchを使ったことがない方は読まなくても問題ありません。「クラスを学ぶとこんなことに使えるんだ」というイメージとして、学習に余裕があるときに読んでみましょう。

PyTorch でニューラルネットワークを作るときは、nn.Module を継承したクラスを書きます。 今学んでいる「クラスの書き方」がそのまま使えます。

sample_4.py
Ctrl+Enter
出力

💡 医療AI文脈: PyTorchでは class MyNet(nn.Module): と書きます。__init__ で層を定義し、forward メソッドで順伝播を実装します。今学んでいるクラスの書き方がそのまま活きます。

なお class MyNet(nn.Module):(nn.Module)継承という仕組みで、既存のクラスの機能を引き継いで新しいクラスを作れます。継承についてはレッスン14で詳しく学びます。今は「クラスを定義するときに別のクラスを組み合わせられる」というイメージだけ持っておきましょう。

5. 練習問題

問題 1

Patientクラスの作成

Patient クラスを作成してください。属性は name(名前)・age(年齢)・blood_type(血液型)。introduce() メソッドで「○○さん(△歳・□型)」と表示できるようにしてください。

exercise_1.py
出力
ヒントを見る(答え+解説)
class Patient:
    def __init__(self, name, age, blood_type):
        self.name = name           # ① 受け取った name を self.name として保存
        self.age = age             # ② 受け取った age を self.age として保存
        self.blood_type = blood_type  # ③ 受け取った blood_type を保存

    def introduce(self):
        # self.xxx で保存したインスタンス変数にアクセス
        print(f"{self.name}さん({self.age}歳・{self.blood_type}型)")

p = Patient("田中太郎", 45, "A")
p.introduce()   # → 田中太郎さん(45歳・A型)

__init__ の役割は「受け取った値を self.xxx に入れて保存すること」です。こうしておけば、introduce などの他のメソッドから self.name などでアクセスできます。

問題 2

BMI計算メソッドの追加

上記の Patient クラスに weight(体重kg)と height(身長m)を追加し、bmi() メソッドでBMI値を返してください。BMI = 体重 ÷ 身長²

exercise_2.py
出力
ヒントを見る(答え+解説)
class Patient:
    def __init__(self, name, age, weight, height):
        self.name = name
        self.age = age
        self.weight = weight    # ← ここを追加
        self.height = height    # ← ここを追加

    def bmi(self):
        return self.weight / (self.height ** 2)  # BMI計算式

    def bmi_category(self):
        b = self.bmi()   # 同じクラスの別メソッドを self. で呼び出せる
        if b < 18.5:
            return "低体重"
        elif b < 25.0:
            return "普通"
        else:
            return "肥満"

p = Patient("田中太郎", 45, 70, 1.75)
print(f"BMI: {p.bmi():.1f}")         # → BMI: 22.9
print(f"判定: {p.bmi_category()}")   # → 判定: 普通

ポイント:bmi_category() の中で self.bmi() と書くと、同じインスタンスの bmi メソッドを呼び出せます。メソッドがメソッドを呼ぶ形です。

問題 3

クラス変数でカウント

Patient クラスにクラス変数 count = 0 を追加し、インスタンスが作られるたびに1増える仕組みを実装してください。最後に「登録患者数: N名」と表示します。

exercise_3.py
出力
ヒントを見る(答え+解説)
class Patient:
    count = 0  # クラス変数(全インスタンスで1つだけ存在)

    def __init__(self, name):
        self.name = name
        Patient.count += 1  # ← クラス名で操作することが重要!

p1 = Patient("田中太郎")
p2 = Patient("山田花子")
p3 = Patient("佐藤次郎")

print(f"登録患者数: {Patient.count}名")  # → 登録患者数: 3名

なぜ self.count += 1 ではなく Patient.count += 1 なのか:

self.count += 1 と書くと、「そのインスタンスだけのインスタンス変数 count」が新しく作られてしまいます。クラス変数 Patient.count は変わらないまま。全員で共有してカウントするには Patient.count でクラス変数を直接変更する必要があります。

まとめ

このレッスンのポイント

  • class クラス名: でクラスを定義し、クラス名(引数) でインスタンスを生成
  • __init__(self, ...) はインスタンス作成時に自動で呼ばれる初期化メソッド
  • self.xxx がインスタンス変数(各インスタンスが独自に持つ)
  • クラス変数はクラス内のインデントレベルで直接定義し、全インスタンスで共有
  • PyTorchの nn.Module もクラス。__init__ で層を定義し forward で計算する

自由に試してみましょう:

free_practice.py
Ctrl+Enter
出力

完了するとトップページに進捗が表示されます