初心者のための@classmethodと@staticmethodの意味 [重複] 質問する

初心者のための@classmethodと@staticmethodの意味 [重複] 質問する

@classmethodPython でとはどのような機能を果たし@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。プロジェクトのソース コードのさまざまな場所でこれを実行する必要があるとします。

したがって、ここで私たちがしなければならないことは次のとおりです。

  1. 文字列を解析して、日、月、年を 3 つの整数変数として、またはその変数で構成される 3 項目のタプルとして受け取ります。
  2. 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. 日付文字列の解析を 1 か所に実装し、再利用できるようになりました。
  2. ここではカプセル化がうまく機能します (文字列解析を他の場所で単一の関数として実装できると思われる場合、このソリューションは OOP パラダイムに非常に適しています)。
  3. 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

おすすめ記事