Pythonの”@classmethod”デコレーターについて解説しています。
@classmethodデコレーターは、使用して、クラス内のメソッド(関数)をクラスメソッドとして宣言し、「ClassName.MethodName()」を使用して呼び出すことができるものです。デコレータとは、構造を変更せずに既存のオブジェクトに新しい機能を追加できる機能。オブジェクトは、特定のクラスのインスタンスであり、文字列、辞書、数値などです。
”@classmethod”デコレーターの特徴としては、クラス メソッドを宣言でき、宣言したクラス メソッドの最初の引数,パラメータは「cls」と設定しなければならない。しかし「cls」の代わりに任意の名前を与えることができるが、「cls」を推奨する。これでクラス属性にアクセスすることができる。クラス属性は、特定のクラス内で定義され、すべてのオブジェクトで使用できる変数のことである。クラスメソッドは「ClassName.MethodName()」を使って呼び出すこともできる、またオブジェクトを使って呼び出すこともできます。
なお、クラスメソッドは、クラス属性にのみアクセスできるものであり、インスタンス属性へアクセスすることはできない。
■Python
今回は、Google Colaboratoryを用います。Google ColaboratoryのPythonのバージョンは、記事作成時点では「3.7.13」となっています。
■”@classmethod”デコレーターを用いてクラスメソッドを宣言する
では、実際に”@classmethod”デコレーターを用いてクラスメソッドを宣言してみます。
■コード
class human: #クラスの定義 name = '日本人' #クラス属性 def __init__(self): self.birthplace = '日本' # インスタンス属性 @classmethod def test_method(cls): print('humanのクラス属性 : name=', cls.name)
今回はhumanというクラスを宣言し、クラス内にnameという変数を定義し、その中に値(文字列)を格納します。これでクラス属性が定義されました。次に、def文を用いて__init__()関数を定義し、括弧内の引数,パラメータとして特別な引数,パラメーターであるself(自己)を渡します。これで、同じオブジェクトの属性などであれば、アクセスできるようになりました。その後、selfに対してドット(.)演算子を用いてbirthplace変数にアクセスし、値(文字列)を格納するようにします。これでインスタンス属性が定義されました。
定義後、「@classmethod」と記述し、def文を用いてtest_methodというクラスメソッドを宣言します。メソッドの括弧内には、「cls」という引数,パラメータを設けます。これで特定のクラス内で定義されたすべてのオブジェクトにアクセスすることができるようになりました。さらにメソッドが呼び出されたときに、実行される処理としては、clsに対してドット(.)演算子を用いてクラス属性にアクセスし、print()でアクセスした値を出力させるというものになります。
■クラスメソッドにアクセスする
human.test_method()
”@classmethod”デコレーターを用いてクラスメソッドを宣言後、「ClassName.MethodName()」を使用して呼び出すことができますので、今回は「human.test_method()」となります。こちらでアクセスしてみます。
アクセスしてみると、「human.test_method()」を使用してクラスメソッドを呼び出し、さらにクラス属性にもアクセスすることができました。
■オブジェクトを使用してメソッドを呼び出す
h_object = human() h_object.test_method()
なお、オブジェクトを使用してメソッドを呼び出すこともできるのでやってみます。まずはh_objectという変数を定義し、その中でhuman()を用いて、オブジェクトを作成するプロセスである「インスタンス化」を行います。その後、オブジェクトに対してドット(.)演算子を用いてクラスメソッドである「test_method()」を指定します。
指定後、実行してみると、オブジェクトを使用してメソッドを呼び出すことができることを確認できました。
■クラスメソッドからインスタンス属性にアクセスするとどうなるのか?
確認後、クラスメソッドからインスタンス属性にアクセスするとどうなるのか、やってみます。
■コード
class human: #クラスの定義 name = '日本人' #クラス属性 def __init__(self): self.birthplace = '日本' # インスタンス属性 @classmethod def test_method(cls): print('humanのクラス属性 : name=',cls.name,', birthplace=', cls.birthplace) h_object = human() h_object.test_method()
インスタンス属性にアクセスするために、「@classmethod」と記述し、def文を用いてtest_methodというクラスメソッドを宣言し、括弧内には、「cls」という引数,パラメータを設けます。これで特定のクラス内で定義されたすべてのオブジェクトにアクセスすることができるようになり、これでインスタンス属性にもアクセスできるようになっているはずです。
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in 9 10 h_object = human() ---> 11 h_object.test_method() in test_method(cls) 6 @classmethod 7 def test_method(cls): ----> 8 print('humanのクラス属性 : name=',cls.name,', birthplace=', cls.birthplace) 9 10 h_object = human() AttributeError: type object 'human' has no attribute 'birthplace'
ですが、このコードを実行してみると、AttributeErrorというエラーが出力され、クラスメソッドからインスタンス属性にアクセスすることができませんでした。
コメント