2012-02-01 2 views
3

는, 작가는 많은 노력이 사용자 정의 메소드 만들고 운영하는 방법을 설명 보냈다 아마도 그 클래스의 IN- 자세)를 통해 클래스 (의 속성 점점 때파이썬 데이터 모델 문서 : (<a href="http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy" rel="nofollow">http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy</a> 참조 : 언 바운드 사용자 정의 메소드 객체와 클래스 메소드 객체 <strong>데이터 모델 기준의</strong>에서

사용자 정의 방식 객체가 생성 될 수있다) 굴러, 그 속성은 사용자 정의 기능 개체인지 , 언 바운드 사용자 정의 메서드 개체 또는 클래스 메소드 객체. 특성이 사용자 정의 메서드 개체 인 경우 새 메서드 개체는 원래 메서드 개체에 저장된 클래스와 동일한 클래스이거나 파생 된 클래스 인 경우에만 생성됩니다 ; 그렇지 않으면 원본 메서드 개체가 그대로 사용됩니다.

그래서 언 바운드 사용자 정의 메소드 객체의 차이는 무엇 클래스 메소드 객체 ?

답변

6

"사용자"관점에서 볼 때 Python의 클래스 메소드는 클래스의 인스턴스를 첫 번째 매개 변수로받는 "일반"메소드와 달리 클래스를 첫 번째 매개 변수로받는 메소드입니다. self이라고합니다.

클래스의 인스턴스가 아닌 클래스에서 "일반"메소드를 검색하면 "언 바운드 메소드"가 생깁니다. 즉 함수를 감싸는 래퍼이지만 자동으로 추가하지는 않는 객체 클래스 자체 또는 호출 될 때 첫 번째 매개 변수로 인스턴스. 따라서 "언 바운드 메서드"를 호출하려면 해당 클래스의 인스턴스를 첫 번째 매개 변수로 수동으로 전달해야합니다. 수동으로 클래스 메소드를 호출 할 경우, 다른 한편으로는, 클래스는 당신을위한 첫 번째 매개 변수로 채워집니다

: 더 많거나 적은 같은 것입니다 어떤 일이 일어나는지 후드에서

>>> class A(object): 
... def b(self): 
...  pass 
... @classmethod 
... def c(cls): 
...  pass 
... 
>>> A.b 
<unbound method A.b> 
>>> A.c 
<bound method type.c of <class '__main__.A'>> 
>>> A.c() 
>>> A.b() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method b() must be called with A instance as first argument (got nothing instead) 
>>> 

- "로 새로운 스타일 클래스 ":

클래스 본문을 정의 할 때 메서드는 일반 함수 일뿐입니다. 클래스 본문이 끝나면 Python은 클래스의 메타 클래스 (일반적으로 내장 된 type)를 호출하고 매개 변수로 전달합니다 이름, 기본 클래스 및 클래스 본문 사전 이 호출은 클래스를 생성합니다. 파이썬에서 모든 것이 객체이기 때문에 클래스 인 객체입니다.

이제 Python에는 속성 액세스를 사용자 정의하는 멋진 방법이 있습니다. 이른바 "설명자"입니다. 기술자는 __get__ (또는 __set__ 또는 __del__)이라는 메서드를 정의하는 모든 개체입니다. 그러나 여기서는 해당 개체를 신경 쓰지 않습니다. 파이썬에서 클래스 나 객체의 속성에 접근 할 때, 그 속성에 의해 참조 된 객체가 반환됩니다 - 그것이 클래스 속성이고 객체가 기술자 인 경우는 예외입니다. 이 경우 객체 자체를 반환하는 대신 Python은 해당 객체에 대해 __get__ 메서드를 호출하고 결과를 대신 반환합니다. 예를 들어, property__set__, __get____del__을 적절히 구현하는 클래스입니다.

이제 특성을 검색하면 몸체에있는 모든 함수 (또는 데이터 모델 상태 인 클래스 메서드 또는 언 바운드 메서드)에 __get__ 메서드가있어 설명자가됩니다. 기본적으로 각 속성에서 함수 본문에 정의 된대로 함수로 명명 된 객체를 검색하기위한 액세스는 해당 함수 주위에 새로운 객체를 만듭니다. 호출 될 때 첫 번째 매개 변수가 자동으로 채워지는 객체입니다. 예를 들어 method입니다.

예 :

>>> class B(object): 
... def c(self): 
...  pass 
... print c 
... 
<function c at 0x1927398> 
>>> print B.c 
<unbound method B.c> 
>>> b = B() 
>>> b.c 
<bound method B.c of <__main__.B object at 0x1930a10> 

당신이 방법 객체 변환없이 함수 객체를 검색 할 경우, 기술자 트리거하지 않는 클래스의 __dict__ 속성을 통해 수행 할 수 있습니다 :

>>> B.__dict__["c"] 
<function c at 0x1927398> 
>>> B.__dict__["c"].__get__ 
<method-wrapper '__get__' of function object at 0x1927398> 
>>> B.__dict__["c"].__get__(b, B) 
<bound method B.c of <__main__.B object at 0x1930a10>> 
>>> B.__dict__["c"].__get__(None, B) 
<unbound method B.c> 

"클래스 메서드"는 이것들이 내장 된 것으로 명시 적으로 장식 된 다른 유형의 개체입니다. __get__이 호출 될 때 반환되는 개체는 origi 호출시 첫 번째 매개 변수로 cls을 채울 함수입니다.

+0

그래서 바운드/언 바운드 사용자 정의 메서드는 "메서드의 인스턴스"이며 classmethod는 "클래스의 메서드, right? – Determinant

+0

입니다. 즉, 클래스에서 직접 언 바운드 메서드를 호출하려고하면 예외가 발생합니다 이 메소드를 호출하기 위해서는 먼저 객체를 생성 한 다음 "from"메소드를 호출해야합니다. 클래스에서 직접 메소드를 호출하려면 데코레이터 @staticmethod를 사용할 수 있습니다. – Denis

+0

@Denis '@ classmethod'를 사용하면 클래스에 바인딩 된 메서드라고 말할 수 있습니까? – Determinant