7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[ Python ] クラス変数とインスタンス変数

Posted at

classをpythonで宣言する際に、クラス内変数を宣言することがあります。
特にクラス内で値を追加したり削除したりするリストを使いたい場面がよくあります。
クラス内変数の宣言方法や「クラス内変数」という呼び方が実は曖昧な呼び方であったことを知ったので備忘録としてまとめていきます。

以下は、公式ドキュメントから引用しています。

  • 一般的に、インスタンス変数はそれぞれのインスタンスについて固有のデータのためのもので、クラス変数はそのクラスのすべてのインスタンスによって共有される属性やメソッドのためのものです:
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'

同じクラス内で使う変数でも「クラス変数」と「インスタンス変数」が区別されています。

  • クラス変数:全てのインスタンスによって共有される属性。
  • インスタンス変数:1つのインスタンス固有の属性。

すなわち、コンストラクタ以下で宣言する変数

class ***

以下で宣言する変数が異なるということです。
特にクラス変数で宣言してしまうと、全てのインスタンス(ここ大事)で変数が共有されているので、リストや辞書などの値を追加・保持する系のオブジェクトを使用する際には特に注意が必要です。

公式ドキュメントでは、以下のソースコードのようにクラス変数としてlist型objectを宣言すべきでないとしています。

class Dog:

    tricks = []             # mistaken use of a class variable

    def __init__(self, name):
        self.name = name

    def add_trick(self, trick):
        self.tricks.append(trick)

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks                # unexpectedly shared by all dogs
['roll over', 'play dead']

上記の例では、クラス変数として宣言したlist型変数tricksについて、2つの異なるインスタンスdeadd_trickされた値が2つのインスタンスdeで共有されていることわかります。
すなわち、クラス変数は、インスタンスが異なっても変数を共有します。
予期しない動作を防ぐためにも、list型などmutableなオブジェクトはインスタンス変数で使用しましょう。

7
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?