1. ホーム
  2. python

[解決済み] classmethodとdef method(self)はいつ使うべきですか?

2022-12-07 04:05:01

質問

今まで使ったことのない Django アプリを統合しているとき、クラス内部で関数を定義する 2 つの異なる方法を見つけました。著者はそれらを区別して意図的に使用しているようです。最初のものは、私自身がよく使うものです。

class Dummy(object):

    def some_function(self, *args, **kwargs):
        # do something here
        # self is the class instance

もうひとつは、いつ、何のために使うのか理解できないので、ほとんど使うことがないものです。

class Dummy(object):

    @classmethod
    def some_function(cls, *args, **kwargs):
        # do something here
        # cls refers to what?

classmethod というデコレータがpythonのドキュメントに書かれています。

クラスメソッドは、インスタンスメソッドがインスタンスを受け取るのと同じように、暗黙の第一引数としてクラスを受け取ります。 インスタンスメソッドがインスタンスを受け取るように。

ということで、推測ですが cls というのは Dummy そのものを指します。 class インスタンスではない)。私は常にこれを行うことができるので、これが存在する理由を正確に理解していません。

type(self).do_something_with_the_class

これは単にわかりやすくするためなのか、それとも一番大事な、これなしではできない不気味で魅力的なものを見逃してしまったのか?

どのように解決するのですか?

あなたの推測は正しいです - あなたは理解している どのように classmethod が働くのか。

なぜかというと、これらのメソッドはインスタンス上でもクラス上でも呼び出せるからです(どちらの場合も、クラスオブジェクトが第一引数として渡されます)。

class Dummy(object):

    @classmethod
    def some_function(cls,*args,**kwargs):
        print cls

#both of these will have exactly the same effect
Dummy.some_function()
Dummy().some_function()

インスタンスでの使用について : インスタンス上でclassmethodを呼び出すには、少なくとも2つの主な使い方があります。

  1. self.some_function() は、そのバージョンを呼び出します。 some_function の実際の型に対して self の実際の型に対して、その呼び出しがたまたま現れるクラスではなく、(そして、クラスがリネームされても注意を払う必要はありません)、そして
  2. の場合 some_function は何らかのプロトコルを実装するために必要ですが、クラスオブジェクトだけで呼び出すと便利です。

との違いは staticmethod : インスタンスデータにアクセスしないメソッドを定義する方法として、もう一つ staticmethod . これは暗黙の第一引数を全く受け取らないメソッドを作成します。従って、呼び出されたインスタンスやクラスに関する情報は一切渡されません。

In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1)

In [7]: Foo.some_static(1)
Out[7]: 2

In [8]: Foo().some_static(1)
Out[8]: 2

In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2)

In [10]: Bar.some_static(1)
Out[10]: 2

In [11]: Bar().some_static(1)
Out[11]: 2

私が見つけた主な使い道は、既存の関数(これは self を受け取ることを期待しない) をクラス (またはオブジェクト) のメソッドとして適応させることです。