スポンサーリンク

コードが書ける!数式が書ける!AAが書ける!スタンプが貼れる!

無料の匿名掲示板型SNS「このはちゃんねる

新規会員募集中!

【Python】クラス変数とは?共有される変数【入門第33回】

130, 2019-08-26

目次

クラス変数とは?

こんにちは、narupoです。

今回もクラスの話題ですが、今回はクラス変数について解説したいと思います。
クラス変数は、定数を定義するときによく使われます
特徴として、このクラス変数はインスタンスごとに作成されず、ひとつの変数が全ての文脈で共有されます

具体的には↓を見ていきたいと思います。

  • クラス変数の書き方
  • クラス変数とインスタンス変数の違い
  • クラス変数の使い道

クラス変数の書き方

クラス変数はクラスに書きますが、書くところがちょっと変わってます。
クラス変数は↓のように書きます。

class クラス名:
    クラス変数 = 値
    クラス変数 = 値
    ...

たとえば↓のようにです。

class Cat:
    MAX_SPEED = 10

MAX_SPEEDというのがクラス変数です。
インスタンス変数の書き方と比べてみましょう。

class Cat:
    MAX_SPEED = 10

    def __init__(self):
        self.name = 'ミケ'
        self.speed = 4

クラス変数にアクセスするには↓のようにします。

# クラスにドットをつけて参照
Cat.MAX_SPEED

# または、インスタンスにドットをつけて参照
cat = Cat()
cat.MAX_SPEED

インスタンス変数は、インスタンスに保存されるのに対して、クラス変数はクラスに保存されます。
この違いはいったいなんなのでしょうか?

クラス変数とインスタンス変数の違い

インスタンス変数はインスタンスごとに作られます
たとえば↓のようなクラスがあるとして、

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

↓のようにクラスからインスタンスを作ります。

mike = Cat('ミケ')
tama = Cat('タマ')

このとき、miketamaが持つインスタンス変数nameは、それぞれ独立しています。

print(mike.name)
print(tama.name)

独立しているので、たとえばmikenameを変更しても、

mike.name = 'スーパーミケ'

tamanameには影響がありません。
これは、mikenameと、tamanameがそれぞれ違うメモリを確保しているからです
メモリというのは、クラスや変数を作るときにパソコンから分けてもらう作業領域のことです

パソコンよ、おらにメモリを分けてくれ!

いっぽう、クラス変数はインスタンスごとに独立しません。
クラス変数は世界にひとつだけで、すべての文脈で共有されます。

たとえば↓のようなクラスがあるとします。

class Cat:
    MAX_SPEED = 10

このクラス変数MAX_SPEEDを参照するには↓のようにします。

print(Cat.MAX_SPEED)

↑のコードの実行結果は10になります。
それではインスタンスを作って↓のようにしてみましょう。

mike = Cat()
tama = Cat()

print(Cat.MAX_SPEED)
print(mike.MAX_SPEED)
print(tama.MAX_SPEED)

↑のprintはいずれも10と出力されます。
それでは、たとえば↓のようにしてMAX_SPEEDの値を変更してみましょう。

Cat.MAX_SPEED = 123

print(Cat.MAX_SPEED)
print(mike.MAX_SPEED)
print(tama.MAX_SPEED)

このとき、↑の3つのprintは何を出力するのかという話です。
じつは、すべて123と出力されます。
このようにクラス変数は、すべての文脈で共有される変数です。
1か所で行った変更が、ほかの参照にも影響します。

クラス変数の使い道

以上のような特徴を持ったクラス変数ですが、いったいどんな使い道があるのでしょうか?
1つは、定数として使う方法です。

さきほどのMAX_SPEEDが定数です。
定数は、一般的には大文字で書くのが慣例です。
そのためMAX_SPEEDも大文字になっています。

定数とは、定義後に値が変わらない性質を持った数です。
しかし、Pythonには標準で定数を扱う仕組みが用意されていません。
そのため、この定数は見かけ倒しです。

あとは、カウンターをクラス変数に定義して、インスタンスが作られるごとにインクリメント(1増加)させれば、いくつインスタンスが作られているのか測ることも出来ます。
ただ、あまり使い道はありません。
やはりもっともよく使われるのは定数としての役割です。

ほかにはDjangoというWebフレームワークでは、クラス変数にフィールドを定義してそれをもとにインスタンスを作るというアプローチを取っていたりします。
これは簡便で使いやすい設計ですが、あまり一般的ではないと思います。

おわりに

クラス変数はインスタンス変数と比べると使用頻度が少ない変数ですが、憶えておくと便利です。
定数を作りたくなったら、このクラス変数を思い出してみましょう。

以上、次回に続きます。

また見てね

関連動画



投稿者名です。64字以内で入力してください。

必要な場合はEメールアドレスを入力してください(全体に公開されます)。

投稿する内容です。

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク