【Python入門】selfを初心者向けに完全解説!インスタンス変数とメソッドの使い方

 

Pythonのクラスを学ぶ際に必ず出てくる「self」という概念は、初心者の方が最初につまずきやすいポイントの一つです。この記事では、「self」とは何か、なぜ必要なのか、どのように使うのかを、初心者の方にも分かりやすく解説します。selfを理解することで、Pythonのオブジェクト指向プログラミングがしっかりと身に付きます。

selfとは?

selfは、Pythonクラスのメソッド内で「そのインスタンス自身」を参照するための特別な引数です。言い換えると、「今作業しているオブジェクト」を指す代名詞のようなものです。

selfの役割

  • インスタンス変数へのアクセス: そのインスタンス固有のデータにアクセス
  • メソッドの呼び出し: そのインスタンスの他のメソッドを呼び出し
  • インスタンスの識別: 複数のインスタンスを区別

基本的なselfの使い方

1. selfでインスタンス変数にアクセス

class Person:
    def __init__(self, name):
        self.name = name  # selfでインスタンス変数を設定
    
    def greet(self):
        print(f"こんにちは、{self.name}です")  # selfで変数にアクセス

person = Person("田中")
person.greet()  # こんにちは、田中です

2. selfを使わない場合のエラー

class Person:
    def __init__(self, name):
        name = name  # ❌ selfがないとインスタンス変数にならない
    
    def greet(self):
        print(f"こんにちは、{name}です")  # ❌ エラー: nameが定義されていない

3. 複数のインスタンスでのselfの働き

class Counter:
    def __init__(self):
        self.count = 0
    
    def increment(self):
        self.count += 1  # 各インスタンスの個別のcountを操作
    
    def show(self):
        print(f"カウント: {self.count}")

counter1 = Counter()
counter2 = Counter()

counter1.increment()
counter1.increment()
counter2.increment()

counter1.show()  # カウント: 2
counter2.show()  # カウント: 1

selfとインスタンス変数

インスタンス変数の作成と操作

class Student:
    def __init__(self, name, grade):
        self.name = name      # インスタンス変数
        self.grade = grade    # インスタンス変数
        self.scores = []      # インスタンス変数(リスト)
    
    def add_score(self, score):
        self.scores.append(score)  # selfでリストにアクセス
    
    def get_average(self):
        if self.scores:
            return sum(self.scores) / len(self.scores)
        return 0

student = Student("山田", 3)
student.add_score(85)
student.add_score(92)
print(f"平均点: {student.get_average()}")  # 平均点: 88.5

selfを使ったメソッド間の呼び出し

1. インスタンスメソッド同士の呼び出し

class Calculator:
    def __init__(self):
        self.result = 0
    
    def add(self, num):
        self.result += num
        return self
    
    def multiply(self, num):
        self.result *= num
        return self
    
    def show_result(self):
        print(f"結果: {self.result}")
    
    def reset_and_show(self):
        self.result = 0     # 自分のインスタンス変数を操作
        self.show_result()  # 自分のメソッドを呼び出し

calc = Calculator()
calc.add(10).multiply(3).show_result()  # 結果: 30
calc.reset_and_show()  # 結果: 0

2. プライベートメソッドの呼び出し

class BankAccount:
    def __init__(self, balance):
        self.balance = balance
    
    def _validate_amount(self, amount):  # プライベートメソッド
        return amount > 0 and isinstance(amount, (int, float))
    
    def deposit(self, amount):
        if self._validate_amount(amount):  # selfでプライベートメソッド呼び出し
            self.balance += amount
            print(f"{amount}円入金しました")
        else:
            print("無効な金額です")

account = BankAccount(1000)
account.deposit(500)   # 500円入金しました
account.deposit(-100)  # 無効な金額です

実践的なselfの活用例

1. ゲームキャラクタークラス

class Character:
    def __init__(self, name, hp, attack):
        self.name = name
        self.hp = hp
        self.max_hp = hp
        self.attack = attack
    
    def take_damage(self, damage):
        self.hp -= damage
        if self.hp < 0:
            self.hp = 0
    
    def heal(self, amount):
        self.hp += amount
        if self.hp > self.max_hp:
            self.hp = self.max_hp
    
    def is_alive(self):
        return self.hp > 0
    
    def status(self):
        print(f"{self.name}: HP {self.hp}/{self.max_hp}")

hero = Character("勇者", 100, 20)
hero.take_damage(30)
hero.status()  # 勇者: HP 70/100
hero.heal(20)
hero.status()  # 勇者: HP 90/100

2. ショッピングカートクラス

class ShoppingCart:
    def __init__(self):
        self.items = []
        self.total = 0
    
    def add_item(self, name, price, quantity=1):
        item = {
            'name': name,
            'price': price,
            'quantity': quantity
        }
        self.items.append(item)
        self._update_total()  # selfで内部メソッド呼び出し
    
    def _update_total(self):  # プライベートメソッド
        self.total = sum(item['price'] * item['quantity'] for item in self.items)
    
    def remove_item(self, name):
        self.items = [item for item in self.items if item['name'] != name]
        self._update_total()
    
    def show_cart(self):
        for item in self.items:
            print(f"{item['name']}: {item['price']}円 x {item['quantity']}")
        print(f"合計: {self.total}円")

cart = ShoppingCart()
cart.add_item("りんご", 100, 3)
cart.add_item("バナナ", 150, 2)
cart.show_cart()
# りんご: 100円 x 3
# バナナ: 150円 x 2
# 合計: 600円

3. タイマークラス

class Timer:
    def __init__(self):
        self.start_time = 0
        self.end_time = 0
        self.is_running = False
    
    def start(self):
        if not self.is_running:
            self.start_time = 0  # 簡略化
            self.is_running = True
            print("タイマー開始")
    
    def stop(self):
        if self.is_running:
            self.end_time = 10  # 簡略化
            self.is_running = False
            print("タイマー停止")
            self._show_elapsed_time()
    
    def _show_elapsed_time(self):
        elapsed = self.end_time - self.start_time
        print(f"経過時間: {elapsed}秒")

timer = Timer()
timer.start()  # タイマー開始
timer.stop()   # タイマー停止、経過時間: 10秒

selfとクラス変数の違い

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

class Person:
    species = "人間"  # クラス変数(全インスタンスで共有)
    
    def __init__(self, name):
        self.name = name  # インスタンス変数(各インスタンス固有)
    
    def introduce(self):
        print(f"私は{self.name}、{Person.species}です")
        # または
        print(f"私は{self.name}、{self.species}です")

person1 = Person("田中")
person2 = Person("佐藤")

person1.introduce()  # 私は田中、人間です
person2.introduce()  # 私は佐藤、人間です

# クラス変数の変更
Person.species = "ホモサピエンス"
person1.introduce()  # 私は田中、ホモサピエンスです

selfの省略とエラー

よくある間違い

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def method1(self):
        return self.value * 2
    
    def method2():  # ❌ selfを忘れている
        return self.value * 3  # エラー: selfが定義されていない

# obj = MyClass(5)
# print(obj.method2())  # TypeError

正しい書き方

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def method1(self):
        return self.value * 2
    
    def method2(self):  # ✅ selfを含める
        return self.value * 3

obj = MyClass(5)
print(obj.method1())  # 10
print(obj.method2())  # 15

静的メソッドとクラスメソッド

staticmethodとclassmethodでのself

class MathUtils:
    pi = 3.14159
    
    def __init__(self, name):
        self.name = name
    
    def instance_method(self):  # インスタンスメソッド(selfが必要)
        return f"{self.name}による計算"
    
    @staticmethod
    def add(a, b):  # 静的メソッド(selfは不要)
        return a + b
    
    @classmethod
    def get_pi(cls):  # クラスメソッド(clsを使用、selfは不要)
        return cls.pi

# 使用例
utils = MathUtils("計算機")
print(utils.instance_method())  # 計算機による計算
print(MathUtils.add(3, 5))      # 8
print(MathUtils.get_pi())       # 3.14159

selfのベストプラクティス

1. 一貫してselfを使用する

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def get_info(self):
        # ✅ 一貫してselfを使用
        return f"{self.name}さん、{self.age}歳"
    
    def is_adult(self):
        # ✅ selfを明示的に使用
        return self.age >= 18

2. メソッドチェーンでselfを返す

class FluentCalculator:
    def __init__(self, value=0):
        self.value = value
    
    def add(self, num):
        self.value += num
        return self  # メソッドチェーンのためselfを返す
    
    def multiply(self, num):
        self.value *= num
        return self
    
    def result(self):
        return self.value

calc = FluentCalculator(5)
result = calc.add(3).multiply(2).add(1).result()
print(result)  # 17 ((5+3)*2+1)

まとめ

Pythonのselfは、オブジェクト指向プログラミングの基礎となる重要な概念です。selfを正しく理解して使用することで、効果的なクラス設計ができるようになります。

重要なポイント

  • selfはインスタンス自身を参照する
  • メソッドの最初の引数は必ずself
  • インスタンス変数へのアクセスにはselfが必要
  • メソッド間の呼び出しでもselfを使用
  • 静的メソッドではselfは不要

まずは簡単なクラスでselfの使い方を練習し、徐々に複雑なクラス設計にチャレンジしてみましょう。実際にコードを書いて練習することで、selfの概念がしっかりと身に付きます!

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座