初心者のための@classmethodと@staticmethodの意味?
誰かpythonの@classmethod
と@staticmethod
の意味を説明してくれませんか?その違いと意味を知りたいのです。
私が理解している限りでは、@classmethod
はクラスに、それがサブクラスに継承されるべきメソッドであることを伝える、とか。しかし、それにはどんな意味があるのでしょうか?classmethodや
@staticmethodなどの
@` 定義を追加することなく、クラスのメソッドを定義すればいいのでは?
tl;dr: when should I use them, why should I use them, how should I use them?
私はC++をかなり使いこなしているので、より高度なプログラミング・コンセプトを使うことは問題ないでしょう。可能であれば、対応するC++の例を気軽に教えてください。
1526
3
classmethod
と
staticmethodは非常によく似ていますが、両方のエンティティの使用法にはわずかな違いがあります。classmethod
は最初のパラメータとしてクラスオブジェクトへの参照を持たなければなりませんが、staticmethod
はパラメータを一切持つことができません。例
Rostyslav Dzinko'さんの回答はとても適切です。追加のコンストラクタを作成する際に、
@staticmethod
ではなく@classmethod
を選択すべきもう1つの理由を紹介しようと思います。上の例では、Rostyslav 氏はファクトリーとして
@classmethod
のfrom_string
を使用して、他の方法では受け入れられないパラメーターからDate
オブジェクトを作成しています。以下のコードに示すように、@staticmethod
でも同様のことができます。このように、
new_year
とmillenium_new_year
はどちらもDate
クラスのインスタンスです。しかし、よく観察してみると、ファクトリー処理では何があっても
Date
オブジェクトを生成するようにハードコーディングされています。つまり、Date
クラスがサブクラス化されても、サブクラスは(サブクラスのプロパティを持たない)プレーンなDate
オブジェクトを作成するということになります。以下の例を見てください。datetime2
は
DateTimeのインスタンスではありませんか?となっています。それは、
@staticmethod`というデコレータが使われているからです。ほとんどの場合、これは望ましくありません。もし、呼び出したクラスを認識するFactoryメソッドが欲しいのであれば、
@classmethod
が必要になります。Date.millenium`を次のように書き換えます(上のコードで変更になるのはこの部分だけです)。
と書き換えることで、
class
がハードコードされているのではなく、学習されていることがわかります。clsには任意のサブクラスを指定できます。結果として得られる
objectは当然ながら
cls` のインスタンスとなります。これをテストしてみましょう。
理由はご存知の通り、
@staticmethod
の代わりに@classmethod
が使われたからです。@classmethod`とは:このメソッドが呼ばれるとき、(通常のメソッドのように)そのクラスのインスタンスではなく、クラスを第一引数として渡します。つまり、特定のインスタンスではなく、クラスとそのプロパティをそのメソッド内で使用することができます。
staticmethod`とは:このメソッドが呼ばれたときに、(通常のメソッドのように)クラスのインスタンスを渡さないということです。つまり、クラスの中に関数を置くことはできても、そのクラスのインスタンスにアクセスすることはできないということです(これは、メソッドがインスタンスを使用しない場合に便利です)。