クラス変数とクラスメソッド
クッキー型を例に、クラスはオブジェクトの設計図、インスタンスがその実体であると説明しましたが、クラス自身もインスタンス同様にデータとメソッドを持つことができます。ここからは、クラスに焦点をあてて、特定のオブジェクトに依らない共通のデータとメソッドの扱いについて学習しましょう。
クラス変数でインスタンスをカウントする
クラス変数を使って、Cookie
クラスからクッキーが何枚できたかをカウントします。
クッキーの枚数をカウントするには、クッキーインスタンスが生成されるたびにカウントアップする、クラス変数を定義します。クラス変数を初期化メソッドに記述して、初期化メソッドが呼び出されるたびに値が追加されるようにしましょう。
class Cookie:
name = "クッキー"
# クッキーの枚数をカウントするクラス変数を定義する
count = 0
# 初期化メソッドを定義する
def __init__(self, taste):
self.taste = taste
# クラス変数をカウントアップする
Cookie.count += 1
# インスタンスの生成と同時に表示
print(str(Cookie.count)+"枚目:" + self.taste + self.name)
cookie1 = Cookie("プレーン")
cookie2 = Cookie("チョコ")
cookie3 = Cookie("チョコチップ")
実行してみましょう。
1枚目:プレーンクッキー
2枚目:チョコクッキー
3枚目:チョコチップクッキー
クッキーの枚数がカウントできました。
まずクラス変数はcount = 0
を初期値として定義しています。その後の初期化メソッドではCookie.count += 1
と記述することで、初期化メソッドが呼び出されるたびに追加されます。
ここで、注意する点がCookie.count
となっていることです。クラス名Cookie
を記述することでクラス変数を呼び出しています。これをself
としてself.count
と記述するとインスタンス変数を呼び出すことになるため、クラス変数count
は0
のままになってしまいます。
クラスメソッド
クラス変数のようにクラスから呼び出すことができるメソッドのことをクラスメソッドといいます。通常はクラス内でメソッドを定義した場合、このメソッドをインスタンスから呼び出すことはできますが、クラスから呼び出すことはできません。通常のメソッドは、クラスメソッドに対してインスタンスメソッドといいます。
クラスメソッドを定義するには組み込みのデコレータ@classmethod
を使います。また、第1引数はcls
を指定します。これはインスタンスメソッドがself
でインスタンス自身を参照するように、cls
はメソッド内でクラス自身を参照できるようにするための引数です。
クラスメソッドはクラス変数同様、クラスからもインスタンスからも呼び出せるだけでなく、インスタンスを生成しなくても呼び出すことができます。
【書式】クラスメソッドの定義
@classmethod
def メソッド名(cls, 引数2, 引数3,…):
処理内容
また、クラスメソッドを呼び出すときは通常のメソッドと同じように記述します。
【書式】クラスメソッドを実行する
クラス名(またはインスタンス名).メソッド名(引数2, 引数3,…)
では、簡単な例でクラスメソッドとインスタンスメソッドの違いを確認しましょう。
class A:
name = "Aクラス"
def __init__(self, name):
self.name = name
def ins_method(self):
print(self.name + "メソッド")
# クラスメソッドを定義する
@classmethod
def cl_method(cls):
print(cls.name + "メソッド")
# Aクラスからクラスメソッドを呼び出す
A.cl_method()
# インスタンスを生成して各メソッドを呼び出す
a = A("aインスタンス")
a.ins_method()
a.cl_method()
実行してみましょう。
Aクラスメソッド
aインスタンスメソッド
Aクラスメソッド
このように、クラスメソッドはインスタンスを生成しなくても、クラスのみで呼び出すことができます。また、クラスメソッドもインスタンスメソッドも変数name
を参照していますが、クラスメソッドではクラス、インスタンスどちらで呼び出してもクラス変数を参照しています。
次に、クラスを継承した場合のクラスメソッドについて確認しましょう。
class A:
name = "Aクラス"
@classmethod
def cl_method(cls):
print(cls.name + "メソッド")
# Aクラスを継承してクラス変数nameを更新する
class B(A):
name = "Bクラス"
# 各クラスからクラスメソッドを呼び出す
A.cl_method()
B.cl_method()
# Aクラスのインスタンスでクラスメソッドを呼び出す
a = A()
a.cl_method()
# Bクラスのインスタンスでクラスメソッドを呼び出す
b = B()
b.cl_method()
実行してみましょう。
Aクラスメソッド
Bクラスメソッド
Aクラスメソッド
Bクラスメソッド
継承してもメソッドの内容は変わっていませんが、どのクラスから呼び出すかによって、クラスメソッドが参照するクラス変数が変化しました。cls
がクラス自身を参照していることがわかります。
初学者のためのPython講座 オブジェクト指向編1 オブジェクト指向とは
初学者のためのPython講座 オブジェクト指向編2 クラスとインスタンス
初学者のためのPython講座 オブジェクト指向編3 メソッド
初学者のためのPython講座 オブジェクト指向編4 初期化メソッド
初学者のためのPython講座 オブジェクト指向編5 クラスの継承
初学者のためのPython講座 オブジェクト指向編6 クラス変数とクラスメソッド
初学者のためのPython講座 オブジェクト指向編7 カプセル化
随時追加予定
次回「プロパティ」