@staticmethod vsモジュールレベル関数


21

これは約@staticmethodではありません@classmethod!仕組みはわかっていますstaticmethod。私が知りたいのは、@staticmethodvs。モジュールレベルの関数の適切なユースケースです。

私はこの質問をグーグルで調べましたが、モジュールレベルの関数は静的メソッドよりもPythonに近いため、モジュールレベルの関数が優先されるという一般的な合意があるようです。静的メソッドには、そのクラスにバインドされるという利点があり、そのクラスのみが静的メソッドを使用する場合に意味があります。ただし、Pythonの機能は通常、クラスではなくモジュールによって編成されるため、通常はモジュール関数にすることも理にかなっています。

静的メソッドはサブクラスでオーバーライドすることもできます。これは、見方によっては利点または欠点です。静的メソッドは通常「機能的に純粋」であるため、オーバーライドするのは賢くないかもしれませんが、便利な場合もあります(ただし、これは「便利でありながら絶対にしないでください」という種類の経験でしか教えられないことがあります)。

staticmethodまたはmodule-level関数を使用するための一般的な経験則はありますか?具体的な長所と短所は何ですか(将来の拡張、外部拡張、読みやすさなど)。可能であれば、事例も提供します。

回答:


11

技術的には、静的メソッドとモジュール関数はほぼ同じように動作します-どちらの場合も、標準関数のように機能しますが、違いはそれらが配置される名前空間です。そのため、決定は保守性/読みやすさの1つです。

通常、これらの基準の一部またはすべてが満たされている場合、静的メソッドを使用します。

  • 通常のメソッドを持つ既存のクラスが既に存在します
  • この関数は、一般的にクラスのオブジェクトに関連していますが、特定のインスタンスには関連していません
  • メソッドを非静的メソッドであるかのように呼び出すことができます。これは、おそらくクライアントコードを壊すことなく、メソッドを非静的にしたい場合があるためです。

0

プログラムは、現実の一部のシミュレーションです。このように、それはあなたが現実をどのように認識するかに依存します。

関数は何らかのアクティビティを表します。アクティビティが一般的であるほど、関数でアクティビティをシミュレートする傾向が大きくなります。メソッドはクラスにバインドされます。アクティビティがクラスに固有であるほど、メソッドによってシミュレートされる傾向が高くなります。

三角関数について考えてください。セイ、sin()とてもよくあなたが、それは角度で収まる知っていることが知られています。入力として浮動小数点数が必要であり、浮動小数点数を返すことがわかっています。とにかく、クラスで表される角度データ型.sin()があり、引数なしは角度オブジェクトで動作する通常のメソッドであり.sin(x)、単一の引数でクラスの静的メソッドである可能性があります。sin()単純な関数を作成する方が良いと考える人が増えることは間違いないでしょう。彼らはより慣れています。

別の視点:モジュールはクラスインスタンスに似ています。独自のメンバー変数とメンバー関数があります。ある意味では、シングルトンパターンを実装します。アプリケーションの別のモジュールからインポートするたびに、まったく同じ変数と関数にアクセスできます。


0

オブジェクトの深いデータ階層の一部を引数として取る関数があります。データ階層のその部分に到達するために必要ないくつかの引数を代わりに渡すのは面倒です。したがって、selfまたはclsを参照する理由はありません。ただし、機能は特定のクラスのオブジェクトの一部でのみ使用されます。だから、私にはクラスメソッドのようです。

さらに、クラス名(「import module」ではなく「from module import class」)をインポートすることを好みます。関数を静的メソッドとして含めると、メソッドにアクセスできますが、モジュールレベルの関数としてメソッドを記述すると、別のインポートが必要になります。


2
もし私があなただったら、私は最初の人に答えることを避けます。ややこしい。代わりに、2番目の人を質問者に書いてください。
アーロンホール

おそらく。ユースケースの例を提供しました。これは、質問者が考えていたものと一致する場合と一致しない場合があります。
Dvd Avins
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.