Python の @staticmethod と @classmethod の違いは何ですか? 質問する

Python の @staticmethod と @classmethod の違いは何ですか? 質問する

メソッドの違いは何ですか装飾された@staticmethodそして、@classmethod?

ベストアンサー1

少しサンプルコードが役に立つかもしれません: 、および の呼び出しシグネチャの違いに注意しくださいfoo:class_foostatic_foo

class A(object):
    def foo(self, x):
        print(f"executing foo({self}, {x})")

    @classmethod
    def class_foo(cls, x):
        print(f"executing class_foo({cls}, {x})")

    @staticmethod
    def static_foo(x):
        print(f"executing static_foo({x})")

a = A()

以下は、オブジェクト インスタンスがメソッドを呼び出す通常の方法です。オブジェクト インスタンスはa、最初の引数として暗黙的に渡されます。

a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>, 1)

クラスメソッドを使用すると、 の代わりにオブジェクトインスタンスのクラスが暗黙的に最初の引数として渡されますself

a.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)

クラスを使用して呼び出すこともできますclass_foo。実際、何かをクラスメソッドとして定義する場合、それはおそらくクラスインスタンスからではなくクラスから呼び出すことを意図しているためです。TypeError がA.foo(1)発生しますが、A.class_foo(1)問題なく動作します。

A.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)

クラスメソッドの用途の1つは、継承可能な代替コンストラクタ


staticmethods ではself(オブジェクト インスタンス) もcls(クラス) も暗黙的に最初の引数として渡されません。インスタンスまたはクラスから呼び出すことができる点を除けば、これらは単純な関数のように動作します。

a.static_foo(1)
# executing static_foo(1)

A.static_foo('hi')
# executing static_foo(hi)

静的メソッドは、クラスと何らかの論理的な接続を持つ関数をクラスにグループ化するために使用されます。


fooは単なる関数ですが、 を呼び出すとa.foo関数が取得されるだけでなく、a関数の最初の引数としてバインドされたオブジェクト インスタンスを持つ関数の「部分的に適用された」バージョンが取得されます。 はfoo2 つの引数を期待しますが、 はa.foo1 つの引数のみを期待します。

aは にバインドされますfoo。これが、以下の「バインド」という用語の意味です。

print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>

の場合a.class_foo、はaにバインドされずclass_foo、クラスAは にバインドされますclass_foo

print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>

ここでは、静的メソッドはメソッドであるにもかかわらず、a.static_foo引数がバインドされていない古き良き関数を返すだけです。 はstatic_foo1 つの引数を期待し、a.static_fooも 1 つの引数を期待します。

print(a.static_foo)
# <function static_foo at 0xb7d479cc>

もちろん、代わりにstatic_fooクラスを呼び出す場合も同じことが起こりますA

print(A.static_foo)
# <function static_foo at 0xb7d479cc>

おすすめ記事