AI資格ドリル
資格を選ぶ

用語比較

クラス変数とインスタンス変数の違い|kindとself.nameの区別をPython3エンジニア認定基礎試験で判断する

クラス変数はそのクラスのすべてのインスタンスで共有される属性、インスタンス変数はそれぞれのインスタンスに固有のデータで、違いは値を共有する範囲です。公式チュートリアルは、前者の例に kind = 'canine'、後者の例に self.name = name を挙げています。

Python 3 エンジニア認定基礎試験では、変数がクラス定義の直下か self. の後かで、変更が他のインスタンスに影響するかを判断させる問題が出ます。

この記事の根拠と出典

各セクションの見出しの下に、公式資料で確認した内容か編集部の整理かをラベルで示しています。 試験日・料金・申込条件・試験方式は変わることがあるため、申込前に公式サイトで確認してください。

クラス変数とインスタンス変数の要点

クラス変数

そのクラスのすべてのインスタンスによって共有される属性。kind = 'canine'のようにクラス定義の直下に書く。

インスタンス変数

それぞれのインスタンスについて固有のデータ。self.name = nameのようにself.を付けて書く。

違いを表で確認

比較軸クラス変数インスタンス変数
公式チュートリアルの説明「そのクラスのすべてのインスタンスによって共有される属性」「それぞれのインスタンスについて固有のデータ」
書き方の例kind = 'canine'(クラス定義の直下)self.name = name(__init__内でselfを付ける)
値を変更した影響範囲同じクラスの全インスタンスに影響しうるそのインスタンスだけに閉じる
可変オブジェクト(list・dict)を使う場合の注意全インスタンスで共有されてしまう場合がある各インスタンスが自分専用のオブジェクトを持つ

Python3エンジニア認定基礎試験の学習に使う書籍(Amazon)

PR

ほかの資格を含む参考書・問題集の一覧を見る

どこで迷っているかを切り分ける

01

クラス変数とインスタンス変数を「どちらもクラスの変数」とまとめて覚えている初学者

kind = 'canine'のようにクラス定義の直下に書けばクラス変数、self.name = nameのようにself.を付けて書けばインスタンス変数です。書かれている場所で区別します。

02

クラス変数を書き換えたら他のインスタンスも変わって驚く人

d.kind = 'canine2'のようにインスタンス経由で単純代入すると、そのインスタンスだけに新しい属性が作られ、他のインスタンスには影響しません。公式チュートリアル9.4節のWarehouse例が示すように、共有が見えるのはDog.kind = 'canine2'のようにクラス経由で代入した場合か、tricksのような可変オブジェクトをappendなどで変更した場合です。

03

クラス変数にリストや辞書を使い、意図せず全インスタンスで共有してしまう人

公式チュートリアルは、リストや辞書のような可変オブジェクトをクラス変数にすると全インスタンスで共有されてしまう場合があると注意しています。インスタンスごとに別々のリストを持たせたい場合は、self.を付けたインスタンス変数として__init__内で作ります。

問題文から答えを選ぶ手順

  1. 1

    変数がクラス定義の直下に書かれているか確認する

    メソッドの外、クラス定義の直下に書かれていればクラス変数です。

  2. 2

    self.が付いているか確認する

    __init__などメソッド内でself.変数名 = 値の形で書かれていればインスタンス変数です。

  3. 3

    変更が他のインスタンスに影響するか考える

    クラス変数への変更は同じクラスの他のインスタンスにも影響しうり、インスタンス変数への変更はそのインスタンスだけに閉じます。

  4. 4

    list・dictのような可変オブジェクトをクラス変数にしていないか確認する

    していれば、全インスタンスで共有されてしまう場合がある点に注意します。

試験での見分け方

  • 1クラス定義の直下に書かれた変数(例: kind = 'canine')はクラス変数で、全インスタンスに共有される。
  • 2self.を付けて書かれた変数(例: self.name = name)はインスタンス変数で、そのインスタンスに固有。
  • 3クラス変数にリストや辞書のような可変オブジェクトを使うと、全インスタンスで共有されてしまう場合がある。
  • 4変更が他のインスタンスに影響するかどうかで、クラス変数かインスタンス変数かを判断する。
  • 5第9章の作問者分析では、「クラス変数とインスタンス変数の混同」がひっかけとして挙げられている。

誤答しやすい選択肢

クラス変数とインスタンス変数を区別せず、どちらも「そのインスタンスだけの値」だと思う

修正: クラス変数は公式チュートリアルの言う「そのクラスのすべてのインスタンスによって共有される属性」ですが、d.kind = 'x'のようにインスタンス経由で単純代入すると、そのインスタンスだけに新しい属性が作られ、他のインスタンスには影響しません。共有が見えるのはクラス経由の代入か、可変オブジェクトをappendなどで変更した場合です。self.を付けたインスタンス変数はそのインスタンスだけに閉じます。

クラス変数にリストや辞書を使い、意図せず全インスタンスで共有してしまう

修正: 公式チュートリアルは、リストや辞書のような可変オブジェクトをクラス変数にすると全インスタンスで共有されてしまう場合があると注意しています。インスタンスごとに別々の値を持たせたい場合はself.を付けたインスタンス変数にします。

self.を付け忘れたまま、インスタンス変数のつもりで書く

修正: self.を付けずにクラス定義の直下に書いた変数はクラス変数として扱われます。インスタンスごとに固有の値にしたい場合は、__init__内でself.変数名 = 値のように書きます。

確認問題

Q1class Dog: kind = 'canine' という書き方のkindはどちらの変数?

答え: クラス変数

kind = 'canine'はクラス定義の直下に書かれており、公式チュートリアルの言う「そのクラスのすべてのインスタンスによって共有される属性」です。

Q2__init__内でself.name = nameと書いたnameはどちらの変数?

答え: インスタンス変数

self.を付けて書かれているため、公式チュートリアルの言う「それぞれのインスタンスについて固有のデータ」です。

Q3クラス変数にリストを使い、あるインスタンスからそのリストへ要素を追加すると、他のインスタンスから見た結果は?

答え: 追加した要素が見える

クラス変数は全インスタンスで共有されるため、公式チュートリアルはリストのような可変オブジェクトをクラス変数にすると全インスタンスで共有されてしまう場合があると注意しています。

Q4あるインスタンスでself.name = '新しい値'と代入した場合、他のインスタンスのnameは変わる?

答え: 変わらない

self.を付けたインスタンス変数はそのインスタンスに固有のデータのため、他のインスタンスには影響しません。

到達チェック

  • クラス変数が全インスタンスで共有される属性だと説明できる
  • インスタンス変数がそのインスタンスに固有のデータだと説明できる
  • kind = 'canine'とself.name = nameの書き方の違いを挙げられる
  • クラス変数に可変オブジェクトを使う際の注意点を説明できる

同じ資格で次に知りたいこと

よくある質問

Qクラス変数とインスタンス変数はどちらを使えばいい?

A

全インスタンスで共有したい値はクラス変数、インスタンスごとに違う値を持たせたい場合はインスタンス変数を使います。

Qself.を付けずにクラス定義の直下に書いた変数はどちらになる?

A

クラス変数です。self.を付けてメソッド内で書いた場合だけインスタンス変数になります。

Qクラス変数にリストを使うと何に注意が必要?

A

公式チュートリアルは、リストや辞書のような可変オブジェクトをクラス変数にすると全インスタンスで共有されてしまう場合があると注意しています。インスタンスごとに別々にしたい場合はインスタンス変数にします。

Qself.name = nameのnameは常にインスタンス変数になる?

A

なります。self.を付けて代入している限り、そのインスタンスに固有のデータとして扱われます。

次に見る比較

執筆: AI資格ドリル編集部(運営者情報を見る)