【Python】クラス変数とは?共有される変数【入門第33回】
目次
クラス変数とは?
こんにちは、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('タマ')
このとき、mike
とtama
が持つインスタンス変数name
は、それぞれ独立しています。
print(mike.name) print(tama.name)
独立しているので、たとえばmike
のname
を変更しても、
mike.name = 'スーパーミケ'
tama
のname
には影響がありません。
これは、mike
のname
と、tama
のname
がそれぞれ違うメモリを確保しているからです。
メモリというのは、クラスや変数を作るときにパソコンから分けてもらう作業領域のことです。
パソコンよ、おらにメモリを分けてくれ!
いっぽう、クラス変数はインスタンスごとに独立しません。
クラス変数は世界にひとつだけで、すべての文脈で共有されます。
たとえば↓のようなクラスがあるとします。
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フレームワークでは、クラス変数にフィールドを定義してそれをもとにインスタンスを作るというアプローチを取っていたりします。
これは簡便で使いやすい設計ですが、あまり一般的ではないと思います。
おわりに
クラス変数はインスタンス変数と比べると使用頻度が少ない変数ですが、憶えておくと便利です。
定数を作りたくなったら、このクラス変数を思い出してみましょう。
以上、次回に続きます。
また見てね
関連動画