@classmethod
Python でとはどのような機能を果たし@staticmethod
、どのような違いがあるのでしょうか?これらはいつ、なぜ、どのように使用すればよいのでしょうか?
私の理解する限りでは、@classmethod
クラスに、サブクラスに継承されるべきメソッドである、などと伝えます。しかし、その意味は何でしょうか? 定義を追加したりせずに、クラス メソッドを定義しないのはなぜでしょう@classmethod
か?@staticmethod
@
ベストアンサー1
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
このクラスは明らかに、特定の日付に関する情報 (タイムゾーン情報なし、すべての日付が UTC で表示されるものと仮定) を保存するために使用できます。
ここでは__init__
、Python クラス インスタンスの典型的な初期化子である があり、これは典型的なインスタンス メソッドとして引数を受け取り、新しく作成されたインスタンスへの参照を保持する最初の非オプション引数 ( self
) を持ちます。
クラスメソッド
sを使用してうまく実行できるタスクがいくつかありますclassmethod
。
外部ソースから取得し、「dd-mm-yyyy」形式の文字列としてエンコードされた日付情報を持つクラス インスタンスを多数作成するとしますDate
。プロジェクトのソース コードのさまざまな場所でこれを実行する必要があるとします。
したがって、ここで私たちがしなければならないことは次のとおりです。
- 文字列を解析して、日、月、年を 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
、クラスが何であるかにアクセスすることはできません。基本的には単なる関数であり、構文的にはメソッドのように呼び出されますが、オブジェクトとその内部 (フィールドやその他のメソッド) にはアクセスできませんclassmethod
。