[解決済み] 初心者のための@classmethodと@staticmethodの意味?[重複あり]
質問
の意味を誰か説明してください。
@classmethod
と
@staticmethod
をpythonで使うことはできますか?その違いと意味を知りたいのです。
私が理解している限りでは
@classmethod
は、そのメソッドがサブクラスに継承されるべきメソッドであることをクラスに伝えるとか...。しかし、その意味は何だろう?なぜ、クラスメソッドを定義するだけで
@classmethod
または
@staticmethod
または任意の
@
の定義は?
tl;dr: いつ を使うべきでしょうか。 なぜ を使うべきであり どのように を使うべきでしょうか?
どのように解決するのですか?
しかし
classmethod
と
staticmethod
は非常によく似ていますが、両エンティティの使い方に若干の違いがあります。
classmethod
は最初のパラメータとしてクラスオブジェクトへの参照を持たなければならないのに対して
staticmethod
は、パラメータを全く持たないことができます。
例
class Date(object):
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
date2 = Date.from_string('11-09-2012')
is_date = Date.is_date_valid('11-09-2012')
説明
日付情報を扱うクラスの例を考えてみましょう(これが私たちの定型文になります)。
class Date(object):
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
このクラスは明らかに、特定の日付に関する情報を保存するために使用することができます(タイムゾーン情報なし。)
ここで
__init__
という引数を受け取る、Pythonのクラスインスタンスの典型的なイニシャライザーです。
instancemethod
を持ち、最初の非選択的引数 (
self
) は、新しく作成されたインスタンスへの参照を保持します。
クラスメソッド
を使うとうまくいく作業がいくつかあります。
classmethod
s.
を大量に作りたい場合を考えてみましょう。
Date
クラスのインスタンスは、外部ソースからの日付情報を 'dd-mm-yyyy' のフォーマットでエンコードした文字列として持っています。これをプロジェクトのソースコード内の異なる場所で行う必要があるとします。
では、ここでやらなければならないことは。
- 文字列を解析して、日、月、年を3つの整数型変数、またはその変数からなる3項目のタプルで受け取る。
-
インスタンス化
Date
初期化呼び出しにそれらの値を渡すことによって。
このようになります。
day, month, year = map(int, string_date.split('-'))
date1 = Date(day, month, year)
このため、C++ではオーバーローディングでこのような機能を実装できますが、Pythonにはこのオーバーローディングがありません。その代わりに
classmethod
. もうひとつ、" を作ってみましょう。
コンストラクタ
"です。
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int, date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
date2 = Date.from_string('11-09-2012')
上記の実装をより注意深く見て、どのような利点があるのかを確認してみましょう。
- 日付文字列のパースを一箇所にまとめて実装したので、再利用が可能になりました。
- ここではカプセル化がうまく機能しています(文字列解析を別の場所で1つの関数として実装できると考えると、この解決策はOOPパラダイムにはるかに適合しています)。
-
cls
を保持するオブジェクトです。 クラスそのもの であって、クラスのインスタンスではありません。これはとても素晴らしいことです。Date
クラスでは、すべての子クラスがfrom_string
も定義されている。
静的メソッド
についてはどうでしょうか。
staticmethod
? とよく似ていますね。
classmethod
が、(クラスメソッドやインスタンスメソッドのように)義務的なパラメータは取りません。
次のユースケースを見てみましょう。
何らかの方法で検証したい日付文字列があります。このタスクも論理的に
Date
クラスをインスタンス化する必要はありません。
ここで
staticmethod
が便利です。次のコードを見てみましょう。
@staticmethod
def is_date_valid(date_as_string):
day, month, year = map(int, date_as_string.split('-'))
return day <= 31 and month <= 12 and year <= 3999
# usage:
is_date = Date.is_date_valid('11-09-2012')
の使い方からわかるように
staticmethod
基本的には単なる関数で、構文的にはメソッドのように呼び出されますが、オブジェクトとその内部(フィールドや別のメソッド)にアクセスすることはできません。
関連
-
[解決済み] for'ループでインデックスにアクセスする?
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] オブジェクト名の前のシングルアンダーコアとダブルアンダーコアの意味は何ですか?
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
-
[解決済み] パブリック、プライベート、プロテクトの違いは何ですか?
-
[解決済み] pipとcondaの違いは何ですか?
-
[解決済み] インターフェースとベースクラス
-
[解決済み】forループを使った辞書の反復処理
-
[解決済み】Pythonの「private」メソッドは、なぜ実際にはprivateではないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PythonはWordの読み書きの変更操作を実装している
-
Pythonの@decoratorsについてまとめてみました。
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み】終了コード -1073741515 (0xC0000135)でプロセス終了)
-
[解決済み】Django: ImproperlyConfigured: SECRET_KEY 設定は空であってはならない
-
[解決済み] 'DataFrame' オブジェクトに 'sort' 属性がない
-
[解決済み】cアンダースコア式`c_`は、具体的に何をするのですか?
-
[解決済み】ValueError: xとyは同じサイズでなければならない
-
[解決済み] Pythonでクラスのメンバ変数にアクセスする?
-
[解決済み] staticmethodとclassmethodの違いについて