1. はじめに
Pythonでオブジェクト指向プログラミングを学び始めたとき、多くの人が最初につまずくのが「クラス変数とインスタンス変数の違い」です。
この2つの変数は定義の仕方は似ていますが、使われ方やスコープが異なり、理解しておかないとバグの原因になります。
この記事では、「Python|クラス変数とインスタンス変数の違いと使い分け」というテーマで、初心者にも分かりやすくその違いと使い分け方を解説していきます。
具体的なコード例と実行結果も交えて、実務での使い方や注意点まで丁寧に紹介します。
2. クラス変数とインスタンス変数の違いとは?
クラス変数とは
クラス変数は、クラスに属する変数であり、全インスタンスで共有される変数です。
通常、クラス定義の直下に書きます。
class Dog:
# クラス変数
species = "Canine"
def __init__(self, name):
# インスタンス変数
self.name = name
# インスタンスを作成
dog1 = Dog("Pochi")
dog2 = Dog("Kuro")
print(dog1.name) # インスタンス変数(個別)
print(dog2.name) # インスタンス変数(個別)
print(dog1.species) # クラス変数(共通)
print(dog2.species) # クラス変数(共通)
実行結果:
Pochi
Kuro
Canine
Canine
インスタンス変数とは
インスタンス変数は、各インスタンスごとに保持される変数で、コンストラクタ(__init__
)の中でself
を使って定義します。
まとめ:違いを比較表で確認
項目 | クラス変数 | インスタンス変数 |
---|---|---|
定義場所 | クラス直下 | __init__ などメソッド内 |
アクセス方法 | クラス名.変数名 or インスタンス.変数名 | インスタンス.変数名 |
共有範囲 | 全インスタンスで共有 | 各インスタンスごとに個別 |
3. よくある使い方・応用例
クラス変数の活用例:インスタンス数のカウント
クラス変数は、すべてのインスタンスで共通の情報を持ちたいときに便利です。例えば、「作成されたインスタンスの数を数える」ケースです。
class User:
# インスタンス数をカウントするクラス変数
count = 0
def __init__(self, name):
self.name = name
User.count += 1
# ユーザーを複数作成
u1 = User("Alice")
u2 = User("Bob")
u3 = User("Charlie")
print(f"現在のユーザー数: {User.count}")
実行結果:
現在のユーザー数: 3
インスタンス変数の活用例:個別データの管理
例えば、複数の生徒情報をそれぞれ管理したいとき、名前や点数などをインスタンス変数として保持します。
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
students = [
Student("田中", 85),
Student("佐藤", 92)
]
for student in students:
print(f"{student.name}さんの点数: {student.score}点")
実行結果:
田中さんの点数: 85点
佐藤さんの点数: 92点
4. クラス変数とインスタンス変数の注意点・エラー対策
注意点1:インスタンスからクラス変数を上書きしない
インスタンスからクラス変数に値を代入すると、「新たなインスタンス変数」が作られてしまい、クラス変数とは別物になります。
class Item:
category = "General"
item1 = Item()
item2 = Item()
# クラス変数をインスタンスから上書き
item1.category = "Electronics"
print(item1.category) # Electronics(インスタンス変数として上書きされた)
print(item2.category) # General(クラス変数のまま)
print(Item.category) # General(クラス変数のまま)
実行結果:
Electronics
General
General
クラス変数を正しく変更したいときは、クラス名.変数名
を使うようにしましょう。
注意点2:クラス変数にミュータブル(変更可能)なオブジェクトを使うときの落とし穴
リストや辞書などをクラス変数にすると、インスタンス間でデータが共有されて予期せぬ挙動になることがあります。
class Basket:
items = [] # クラス変数でリストを使う
def add_item(self, item):
self.items.append(item)
b1 = Basket()
b2 = Basket()
b1.add_item("Apple")
b2.add_item("Banana")
print(b1.items)
print(b2.items)
実行結果:
['Apple', 'Banana']
['Apple', 'Banana']
どちらのインスタンスでも同じリストが使われているため、意図しない動作になります。
この場合は、インスタンス変数にするか、毎回コピーする工夫が必要です。
5. まとめ
- クラス変数はクラス全体で共有される変数。共通情報の管理に便利。
- インスタンス変数は各インスタンス固有。個別データの管理に使う。
- 使い分けを間違えるとバグの原因に。特にクラス変数の上書きやミュータブルなデータに注意。
クラス変数とインスタンス変数の違いを正しく理解することで、Pythonのオブジェクト指向設計がよりスムーズになります。
実務でも、設定情報の共有やログインユーザー管理など、さまざまな場面で使われる重要な概念です。
自分のプロジェクトに応じて、どちらが適切か考えながら設計していきましょう!