Class vs Instance Variables

クラス変数とインスタンス変数の区別について説明します。

Rachit Tayal
Rachit Tayal

Follow

6月9日。 2019 – 3 min read

変数とは、本来、プログラム内で使っている値の代わりとなる記号のことです。 オブジェクト指向プログラミングでは、変数をクラスレベルまたはインスタンスレベルで使用することができます。 この記事の目的は、Pythonのオブジェクトモデルが提供する変数の種類を明確に区別することであり、さらに、無視するといくつかの驚くべき結果につながるかもしれない独特の動作について議論することです。
Pythonのオブジェクトモデルに従って、Pythonオブジェクトのデータ属性には2つの種類があります:クラス変数とインスタンス変数。 これらはクラスの特定のオブジェクトに関連付けられないため、クラスのすべてのオブジェクトで共有されます。

インスタンス変数 – クラスのコンストラクタ・メソッド (__init__ メソッド) の内部で宣言されます。

短く、消化しやすい例から始めましょう。

class Car:
wheels = 4 # <- Class variable def __init__(self, name):
self.name = name # <- Instance variable

上記は、基本的で無駄のない Car クラスが定義されています。 その各インスタンスは、インスタンス変数名とともにクラス変数wheelを持つことになる。

>>> jag = Car('jaguar')
>>> fer = Car('ferrari')>>> jag.name, fer.name
('jaguar', 'ferrari')>>> jag.wheels, fer.wheels
(4, 4)>>> Car.wheels
4

インスタンス変数名へのアクセスは、非常に簡単です。 しかし、クラス変数にアクセスする場合は、もう少し柔軟性があります。 インスタンス変数はオブジェクト固有であり、__init__ コンストラクターが呼び出されたときに作成されるため、クラスを通して名前にアクセスしようとすると AttributeError が発生します。 これがクラス変数とインスタンス変数の主な違いです。

>>> Car.name
AttributeError: type object 'Car' has no attribute 'name'

さて、とりあえず、私たちのジャガーの車が 3 つの車輪を持っていると仮定しましょう。 (そう、それは愚かなことですが、我慢してください!😅)。

>>> Car.wheels = 3

上で行ったことは、クラス変数を変更したため、すべての車に 3 つの車輪をつけることになり、それは Car クラスのすべてのインスタンスに適用されます。

>>> Car.wheels = 4
>>> jag.wheels = 3

これは、私たちが望む出力を得ることができます。

>>> jag.wheels, fer.wheels, Car.wheels
(3, 4, 4)

私たちが望む結果を得たが、舞台裏で起こったことは、jagオブジェクトに追加された新しいホイール変数とこの新しい変数は、同じ名前のクラス変数をオーバーライドして隠して、シャドウしているのです。

>>> jag.wheels, jag.__class__.wheels
(3, 4)

したがって、jag.wheels = 3 はクラス変数 (wheels) と同じ名前を持つ新しいインスタンス変数を作成したと結論付けることができます。 これは、注意すべき重要な概念です。
クラスおよびインスタンス固有の変数を使用することで、コード内の繰り返しを減らす DRY 原則に従ったコードを作成することを保証できます。
これを知っていると、本当に便利で、ある日のデバッグにかかる時間を大幅に短縮できると感じています。

結論

  • クラス変数はすべてのオブジェクトで共有され、インスタンス変数はそれぞれのインスタンスに固有のデータ用です。
  • インスタンス変数は同じ名前のクラス変数をオーバーライドするので、コードに偶然バグや驚くべき動作をもたらす可能性があります。

コメントを残す

メールアドレスが公開されることはありません。