2009-11-04 2 views
7

classmethod 객체가 파이썬에서 어떻게 작동하는지 이해하는 데 어려움을 겪고 있습니다. 특히 메타 클래스와 __new__에서 어떻게 작동하는지 이해해야합니다. 내 특별한 경우에 members을 반복 할 때 클래스 메서드 멤버의 이름을 얻고 싶습니다. __new__.classmethod 객체는 어떻게 작동합니까?

일반적인 메서드의 경우 이름은 __name__ 특성에 저장되지만 클래스 메서드에는 해당 특성이 없습니다. __call__ 속성도 없으므로 클래스 메쏘드가 어떻게 호출되는지조차 알지 못합니다.

누군가 클래스 메쏘드가 어떻게 작동하는지 또는 어떤 문서를 가르쳐 줄 수 있습니까? 인터넷 검색은 아무데도 나를 이끌지 못했습니다. 감사!

+0

"누락 된"__name__에 대한 통찰력은 없지만 classmethods에는 '__call__'래퍼가 있는지 확인해야합니다. – mjv

답변

18

classmethod 개체는 설명자입니다. 설명 자의 작동 방식을 이해해야합니다. self, instanceinstance type : 요컨대

는 디스크립터는 세 개의 인자를 취하는 방법 __get__을 갖는 것을 목적으로한다.

일반적인 특성 조회 중에 조회 된 개체 A__get__ 메서드가 있으면 해당 메서드가 호출되고 반환되는 개체는 A 개체로 대체됩니다. 이것은 함수 (descriptors)가 객체의 메소드를 호출 할 때 바운드 메소드가되는 방식입니다.

class Foo(object): 
    def bar(self, arg1, arg2): 
     print arg1, arg2 

foo = Foo() 
# this: 
foo.bar(1,2) # prints '1 2' 
# does about the same thing as this: 
Foo.__dict__['bar'].__get__(foo, type(foo))(1,2) # prints '1 2' 

classmethod 개체는 동일한 방식으로 작동합니다. 찾았을 때 __get__ 메서드가 호출됩니다. 클래스 메서드의 __get__instance (있는 경우)에 해당하는 인수를 무시하고 랩 된 함수에서 __get__을 호출 할 때 instance_type만을 전달합니다.

설명 낙서 :

기술자에

자세한 정보는 (다른 장소들) 여기에서 찾을 수 있습니다

In [14]: def foo(cls): 
    ....:  print cls 
    ....:  
In [15]: classmethod(foo) 
Out[15]: <classmethod object at 0x756e50> 
In [16]: cm = classmethod(foo) 
In [17]: cm.__get__(None, dict) 
Out[17]: <bound method type.foo of <type 'dict'>> 
In [18]: cm.__get__(None, dict)() 
<type 'dict'> 
In [19]: cm.__get__({}, dict) 
Out[19]: <bound method type.foo of <type 'dict'>> 
In [20]: cm.__get__({}, dict)() 
<type 'dict'> 
In [21]: cm.__get__("Some bogus unused string", dict)() 
<type 'dict'> 
: http://users.rcn.com/python/download/Descriptor.htm

classmethod 래핑 함수의 이름을 얻을 수있는 특정 작업을 위해 :

In [29]: cm.__get__(None, dict).im_func.__name__ 
Out[29]: 'foo' 
+0

고맙습니다. 내 문제가 해결되었습니다! 원칙적으로 디스크립터에 대해 알고 있었기 때문에 나는 지금 바보 같다고 느낍니다. 하지만 classmethod가 호출 할 수없는 설명 자로 둘러 쌓여 있다는 것을 혼란스럽게 보았습니다 :-) – nikow

+0

죄송합니다. 매우 상세한 답변을 얼마나 고맙게 여기는 지 잊었습니다. – nikow

1

This 상품이있는 것처럼 보입니다.

+0

감사합니다. Metamethods라는 용어를 알지 못했기 때문에 흥미로운 읽을 거리였습니다. 하지만 클래스 메쏘드 객체 자체에 대한 정보는별로 없었습니다. – nikow