(訳文)Pythonにおけるstaticmethodとclassmethod

3895 ワード

原文はstackoverflowの高票回答で、原文のリンクは以前にも翻訳されたことがあるかもしれませんが、ちょうど自分にも疑問があるので、運んでみてください.個人のレベルが限られているので、翻訳に誤差がある可能性があります.classmethodstaticmethodは非常に似ているが、両者の具体的な使用にはわずかな違いがある.classmethodはクラスオブジェクトを最初のパラメータとして使用しなければならないが、staticmethodはパラメータを渡さなくてもよい.
実際の例を見てみましょう.
かたわく
日付情報を処理するクラスがあると仮定します.
class Date(object):
    day = 0
    month = 0
    year = 0
    
    def __init__(self, day=0, month=0, year=0):
        self.day = day
        self.month = month
        self.year = year

このクラスは、特定の日付情報を格納するために使用できることは明らかです(タイムゾーン情報を考慮しません.すべての日付がUTCで表されていると仮定します).
ここでは、__init__が定義され、典型的なクラスインスタンス初期化方法は、典型的なinstancemethodとしてパラメータを受け入れ、最初の伝達に必要なパラメータは、新しいインスタンス自体である.
クラスメソッドclassmethodを使用することでうまく解決できるタスクがあります.('dd-mm-yyyy')フォーマットの文字列の日付情報がたくさんあると仮定し、Dateクラスのインスタンスに作成します.私たちはプロジェクトの異なる場所でこれらのことをしなければなりません.
次のようにしなければなりません
  • で得られた年月日文字列を解析し,それらを3つの整形変数または3つの要素を持つメタグループの変数に変換した.
  • は、これらの値を伝達することによってDateを例示する.

  • 取得:
    day, month, year = map(int, string_date.splite('-'))
    date1 = Date(day, month, year)

    C++はこのような目的を達成するために重荷の特性を持っているが、Pythonはこのような特性に欠けている-したがって、pythonはclassmethodの方法を使用する.別の構造関数を試してみましょう.
        @classmethod
        def from_string(cls, date_as_string):
            day, month, year = map(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
        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
        
        is_date = Date.is_date_valid('11-09-2012')
    staticmethodの使用を理解したように、所属するクラスにアクセスする必要はありません.本質的には関数であり、呼び出し方法は呼び出し関数と同様に、オブジェクトとオブジェクトの内部属性に注目しないのとは異なります.