2017-11-03 11 views
1

有名な例から、私はPythonクラスのmethod、classmethod、staticmethodの違いを学びました。同じPythonクラスのメソッド、クラスメソッド、静的メソッド

出典: What is the difference between @staticmethod and @classmethod in Python?

class A(object): 
    def foo(self,x): 
     print "executing foo(%s,%s)"%(self,x) 

    @classmethod 
    def class_foo(cls,x): 
     print "executing class_foo(%s,%s)"%(cls,x) 

    @staticmethod 
    def static_foo(x): 
     print "executing static_foo(%s)"%x 
    # My Guesses 
    def My_Question(self,x): 
     self.foo(x) 
     A.class_foo(x) 
     A.static_foo(x) 

a=A() 

今、私はクラス内でメソッド、@classmethod、および@staticmethodを呼び出す方法を、疑問に思って。

私は上記のMy_Question機能に私の推測を入れましたが、私はこれらのいずれかに間違っていれば私を修正してください。

+0

あなたが持っているものは正しいです。すべて3に 'self'を使うこともできます。 – wim

答えて

1

ありがとうございます。 外クラスstaticmethodsとクラスメソッドを呼び出すためにも、通常の/可能であることに注意してください:

class A(): 
    ... 

A.class_foo() 
A.static_foo() 

はまた通常のインスタンスメソッドの内部が、それは(直接インスタンス上staticmethodsとクラスメソッドを呼び出すのが通例だということに注意してくださいむしろクラス(A)よりself):

class A(): 
    def instance_method(self): 
     self.class_foo() 
     self.static_foo() 

継承が機能するためにあなたが期待するかもしれないので、これは許可する - 私はAからBサブクラスを作成する場合は、私はB.instance_method()を呼び出す場合、私のclass_foo機能がcls引数としてBの代わりAを取得します - 私はA.static_fooよりもわずかに異なる何かをするBstatic_fooをオーバーライドする場合は、おそらくそして、これは上書きバージョンが同様に呼び出すことができるようになります。これは、より明確になるかもしれない

いくつかの例は:

class A(object): 
    @staticmethod 
    def static(): 
     print("Static, in A") 

    @staticmethod 
    def staticoverride(): 
     print("Static, in A, overrideable") 

    @classmethod 
    def clsmethod(cls): 
     print("class, in A", cls) 

    @classmethod 
    def clsmethodoverrideable(cls): 
     print("class, in A, overridable", cls) 

    def instance_method(self): 
     self.static() 
     self.staticoverride() 
     self.clsmethod() 
     self.clsmethodoverride() 

class B(A): 
    @classmethod 
    def clsmethodoverrideable(cls): 
     print("class, in B, overridable", cls) 

    @staticmethod 
    def staticoverride(): 
     print("Static, in B, overrideable") 


a = A() 
b = B() 
a.instance_method() 
b.instance_method() 

...

あなたはinstance_methodA.self.のすべてを変更することで、それを試してみてください、ということを実行した後。再実行して比較する。 に電話しているときでも、Bへの参照がすべて消えていることがわかります。このため、クラスではなくselfを使用します。

+0

参照先の記事の一番上の答えで、@classmethodはクラスにバインドされていて、 'self'のような 'cls'を含める必要があります通常のクラスメソッド。私は 'cls'と 'self'が実際の意味を持っているのだろうと思っています。その2つの文字列を使用する必要がありますか?また、なぜself.class_foo(x)の代わりにcls.class_foo(x)を使用しないのですか? –

+0

名前 'self'と' cls'は_conventions_です。任意の名前を使用することができますが、コードを読んでいる人なら誰でも大声で大声で叫ぶでしょう。 'classmethod'では、最初の引数は_class_ですが、通常のメソッドでは最初の引数はクラスの_instance_です。これは、あなたのサンプルコードの 'A'と' a'の違いです。 - なぜ "cls.class_foo(x)'を使わないのか " - 別のクラスメソッドからクラスメソッドを呼び出す場合は、そのクラスを使用する必要があります。インスタンスメソッドでは、 'cls'という名前は定義されていません(私のサンプルコードで試してみてください)。 – mgilson

+0

すごく、ありがとう、私はそれを試みます。 –

0

@ウィムは言ったように、あなたが持っているものは正しいです。 My_Questionが呼び出されたときの出力は次のとおりです。

>>> a.My_Question("My_Answer=D") 
executing foo(<__main__.A object at 0x0000015790FF4668>,My_Answer=D) 
executing class_foo(<class '__main__.A'>,My_Answer=D) 
executing static_foo(My_Answer=D) 
関連する問題