2017-11-03 2 views
1

유명한 예제에서, 나는 Python 클래스에서 method, classmethod 및 staticmethod의 차이점을 배웠다.같은 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() 

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

지금 내가 궁금 클래스 내부 방법, @classmethod@staticmethod를 호출하는 방법에 대해 설명합니다.

나는 위의 My_Question 함수에 내 추측을 넣었으므로,이 중 하나라도 잘못 되었다면 저를 수정하십시오.

+0

당신이 가지고있는 것이 맞습니다. 모든 3에 대해 'self'를 사용하는 것도 가능합니다. – wim

답변

1

네 추측이 가능합니다. 이 클래스 외부 staticmethods 및 classmethods에게 를 호출하는 것이 가능/정상입니다 참고 : 또한

class A(): 
    ... 

A.class_foo() 
A.static_foo() 

내부의 일반 인스턴스 메소드주의, 그것은 (인스턴스에 직접 staticmethods와 클래스 메소드를 호출하는 관례 self)가 아니라 클래스 (A) 이상 :

이 예상대로 작동 상속을 허용
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를 오버라이드 (override)하는 경우는, 가능성 그리고, 이것은 무시 버전뿐만 아니라 호출 할 수 있습니다. 이보다 명확하게 할 수

몇 가지 예 :

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_method 내부 A.self.을 모두 변경하여 시도하는 것이 실행 한 후. 다시 실행하고 비교하십시오. B에 대한 참조가 모두 사라진 것을 볼 수 있습니다 (심지어 b.instance_method()로 전화 한 경우에도 마찬가지입니다). 이 때문에 클래스가 아닌 self을 사용하려고합니다.

+0

참조 된 게시물의 맨 위 대답에서 @classmethod는 클래스에 한정되어 있으며 'self'와 같이 'cls'를 포함해야합니다. 보통의 클래스 메소드. 나는 'cls'와 'self'가 실제 의미를 가지고 있는지 궁금해합니다. 그래서 우리는 그 두 문자열을 사용해야 만합니까? 또한 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

@wim이 말했듯이, 당신이 가진 것이 옳습니다. 다음은 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) 
관련 문제