8

@classmethodPythonの「クラシック」メソッドとの違いは何ですか?

Python でいつを使用し@classmethod、いつ「クラシック」メソッドを使用する必要がありますか。クラスメソッドは、クラスを参照するメソッドでなければなりませんか (つまり、クラスを処理するメソッドのみです)。

そして、@staticmethod と従来のメソッド Thx の違いは何かを知っています

4

3 に答える 3

7

selfクラス内でメソッドを定義すると、特別な方法で処理されます。メソッドへのアクセスは、参照されたオブジェクトへの参照を含めるために呼び出し引数を変更する特別なオブジェクトにラップします。

class A(object):
    def f(self):
        pass

a = A()
a.f()

この への呼び出しは、(記述子プロトコルを介して) オブジェクトが実際に返されることをa.f実際に要求します。次に、このオブジェクトは引数なしで呼び出され、前に追加して、実数への呼び出しをそらします。f fa

したがって、a.f()実際に行うことは、引数として元のf関数を呼び出すことです。(a)

これを防ぐために、関数をラップすることができます

  1. @staticmethodデコレータで、
  2. @classmethodデコレータで、
  3. 他の同様の動作する自作デコレータの 1 つを使用します。

@staticmethodそれをオブジェクトに変換し、要求されたときに、引数を渡す動作を変更して、元の を呼び出す意図と一致するようにしますf

class A(object):
    def method(self):
        pass
    @staticmethod
    def stmethod():
        pass
    @classmethod
    def clmethod(cls):
        pass

a = A()
a.method() # the "function inside" gets told about a
A.method() # doesn't work because there is no reference to the needed object
a.clmethod() # the "function inside" gets told about a's class, A
A.clmethod() # works as well, because we only need the classgets told about a's class, A
a.stmethod() # the "function inside" gets told nothing about anything
A.stmethod() # works as well

したがって@classmethod@staticmethodそれらが呼び出された具体的なオブジェクトを「気にしない」という共通点があります。違いは、@staticmethodそれについて何も知りたくないのに対し、@classmethodそのクラスを知りたいということです。

したがって、後者は、使用されたオブジェクトがインスタンスであるクラス オブジェクトを取得します。この場合は にself置き換えるだけです。cls

さて、いつ何を使う?

まあ、それは扱いやすいです:

  • にアクセスできる場合は、self明らかにインスタンス メソッドが必要です。
  • にアクセスしないselfが、そのクラスについて知りたい場合は、 を使用します@classmethod。これは、たとえば、ファクトリ メソッドの場合に当てはまります。datetime.datetime.now()はその例です。クラスまたはインスタンスを介して呼び出すことができますが、まったく異なるデータで新しいインスタンスを作成します。特定のクラスのサブクラスを自動的に生成するために、それらを一度使用しました。
  • selfどちらも必要ない場合はcls、を使用します@staticmethod。これは、サブクラス化を気にする必要がない場合、ファクトリ メソッドにも使用できます。
于 2013-07-31T08:33:31.637 に答える
7

システム内のエンティティCarを表すクラスがあるとします。Car

Aは、のインスタンスのいずれにもないclassmethodクラスに対して機能するメソッドです。したがって、通常は と呼ばれるで装飾された関数の最初のパラメーターは、クラス自体です。例:CarCar@classmethodcls

class Car(object):    
    colour = 'red'

    @classmethod
    def blue_cars(cls):
        # cls is the Car class
        # return all blue cars by looping over cls instances

関数はクラスの特定のインスタンスに作用します。通常呼び出される最初のパラメーターselfは、インスタンス自体です。

def get_colour(self):
    return self.colour

総括する:

  1. classmethod(特定のクラス インスタンスではなく) クラス全体で機能するメソッドを実装するために使用します。

    Car.blue_cars()
    
  2. インスタンス メソッドを使用して、特定のインスタンスで動作するメソッドを実装します。

    my_car = Car(colour='red')
    my_car.get_colour() # should return 'red'
    
于 2013-07-31T08:36:11.803 に答える
3

@classmethodクラスを最初の引数として取り、関数はクラスのインスタンスを取ります

>>> class Test(object):
...     def func(self):
...         print self
...     @classmethod
...     def meth(self):
...         print self

>>> t = Test()
>>> t.func()
<__main__.Test object at 0x00000000027238D0>
>>> t.meth()
<class '__main__.Test'>

self引数 in を意図的に使用しmethたので、構文が に非常に近くなりますfunc。ただし、通常はcls引数として使用することをお勧めします。

...     @classmethod
...     def meth(cls):
...         print cls
于 2013-07-31T08:36:07.153 に答える