Pythonのクラス変数とインスタンス変数の違いを徹底解説
Pythonでは、__init__()関数の外側で定義された変数は「クラス変数」、内側で定義された変数は「インスタンス変数」と呼ばれます。この2つは似たように見えますが、動作が大きく異なるため、その違いを正しく理解することが重要です。
クラス変数とインスタンス変数の違いとは?
クラス変数は、クラス自体に紐づく変数で、そのクラスから生成されたすべてのインスタンス(オブジェクト)によって共有されます。一方、インスタンス変数は、各オブジェクトごとに独立して保持される変数です。
以下のコード例を見ると、両者の違いがより明確に理解できます。
コード例
class MyClass:
stat_elem = 456 # クラス変数(__init__の外側)
def __init__(self):
self.object_elem = 789 # インスタンス変数(__init__の内側)
c1 = MyClass()
c2 = MyClass()
# 両方の要素の初期値を確認
>>> print(c1.stat_elem, c1.object_elem)
456 789
>>> print(c2.stat_elem, c2.object_elem)
456 789
# クラス変数を変更してみる
MyClass.stat_elem = 888
>>> print(c1.stat_elem, c1.object_elem)
888 789
>>> print(c2.stat_elem, c2.object_elem)
888 789
# 次に、インスタンス変数を変更してみる
c1.object_elem = 777
>>> print(c1.stat_elem, c1.object_elem)
888 777
>>> print(c2.stat_elem, c2.object_elem)
888 789
結果の解説
① クラス変数を変更した場合
MyClass.stat_elem = 888のようにクラス変数を変更すると、c1とc2のどちらのオブジェクトから参照しても値が「888」に変わりました。これは、クラス変数がすべてのインスタンスで共有されていることを示しています。
② インスタンス変数を変更した場合
一方、c1.object_elem = 777のようにインスタンス変数を変更すると、c1の値だけが「777」になり、c2は元の「789」のままでした。これは、インスタンス変数が各オブジェクトごとに独立していることを示しています。
使い分けのポイント
- クラス変数: 全インスタンスで共有したい定数やカウンタなどに適しています。
- インスタンス変数: オブジェクトごとに異なる状態(名前、IDなど)を持たせたい場合に使用します。
なお、注意点として、c1.stat_elem = 値のようにインスタンス経由でクラス変数と同名の変数に代入すると、それは新しいインスタンス変数として作成され、クラス変数自体は変更されません。クラス変数を変更したい場合は、必ずクラス名.変数名の形式でアクセスしましょう。
-
Pythonの名前空間と変数のスコープを徹底解説!LEGBルールで名前解決の仕組みを理解しよう
Pythonにおける名前空間(Namespace)とは?名前空間(Namespace)とは、変数名とその実体(オブジェクト)を対応付ける仕組みであり、スコープを実現するための基盤となるものです。Pythonでは、パッケージ・モジュール・クラス・関数・メソッドといったそれぞれの単位が、独自の「名前空間」を持っています。関数やモジュール、パッケージが評価されて実行が始まると、そのための名前空間が新しく作成されます。これは「評価コンテキスト」と考えると分かりやすいでしょう。そして、実行が終了すると、その名前空間は破棄され、そこに存在していた変数も一緒に消えます。さらに、ローカルの名前空間に目的の名前
-
Pythonのグローバル変数とローカル変数の違いとは?わかりやすく解説
Pythonにおいて、グローバル変数とはプログラム全体(モジュール内のどこからでも)アクセスできる変数のことです。一方、ローカル変数は特定のスコープ内、たとえば関数定義の中でのみアクセスできる変数であり、関数内で一時的に使用される変数などがこれに該当します。コード例以下のコードを見てみましょう。q = I love coffee # グローバル変数 def f(): p = Me Tarzan, You Jane. # ローカル変数 print(p) f() print(q)実行結果このコードを実行すると、次のような出力が得られます。Me Tarzan, You Jan