2017-01-17 6 views
4

나는 classmethods의 개념을 파이썬으로 배우고 있습니다. 파이썬 classmethods 클래스에서 호출 할 수 없습니다 .__ dict__

class A(): 
    n=0 
    # object method 
    def func_o(self): 
     self.n += 1 
     print self.n 

    # well, class method 
    @classmethod 
    def func_c(cls): 
     cls.n += 1 
     print cls.n 

클래스의 callable() 속성을 확인

,이 독특한 출력에서 ​​온 :

클래스 __dict__이 검사에도 불구하고
>>> [(k, callable(v)) for k,v in A.__dict__.items()] 
[('__module__', False), ('__doc__', False), ('func_o', True), ('func_c', False), ('n', False)] 

('func_o', True), 유사 ('func_c', False)을 어떤 이유로.

누군가 설명 할 수 있습니까?

답변

5

classmethod 개체는 함수 개체가 아닙니다. 호출 할 수있는 것은 아닙니다.

classmethod 개체는 설명자입니다. 기술자는 객체를 특정 인스턴스 나 클래스에 바인딩하는 것을 용이하게한다. 함수 및 속성도 설명자입니다. 바인딩은 각각 메소드 또는 특성 값을 생성합니다. Python Descriptor How To을 참조하십시오. 클래스의 classmethod 설명자에 액세스하는 경우 바인딩 된 메서드 (호출 될 때 클래스 개체가 첫 번째 인수로 전달 된 원래 함수를 호출 함)를 생성하는 classmethod.__get__(None, cls) 호출을 트리거합니다.

__dict__ 특성을 통해 모든 클래스 특성에 액세스하면 설명자 프로토콜을 무시하므로 원시 설명자 개체를 직접 얻을 수 있습니다.

명시 적으로 classmethod 객체의 클래스에있는 개체에 액세스 (따라서 클래스 객체에 클래스 메소드를 결합하는 descriptor.__get__(None, cls) 호출을 트리거), 수동으로 결합, 또는 테스트 :

>>> A.__dict__['func_c'] 
<classmethod object at 0x1018e6cc8> 
>>> A.__dict__['func_c'].__get__(None, A) # explicitly bind to a class 
<bound method classobj.func_c of <class __main__.A at 0x101c52328>> 
>>> callable(A.__dict__['func_c'].__get__(None, A)) 
True 
>>> A.func_c # trigger the protocol and bind to a class 
<bound method classobj.func_c of <class __main__.A at 0x101c52328>> 

또한 액세스 할 수있는 원래 함수 __func__ 특성을 이용하여 객체 classmethod 래핑한다 :도 물론이다

>>> A.__dict__['func_c'].__func__ 
<function func_c at 0x101c59668> 

자체 호출.

이 모두가 staticmethod 개체에도 적용됩니다. staticmethod 개체는 바인딩 될 때 원래 함수를 반환합니다.