2014-06-23 5 views
47

첫 번째 결과가 False 인 이유는 무엇입니까? True이 아니어야합니까?연산자의 아주 이상한 동작은 메서드가있는 'is'입니다.

>>> from collections import OrderedDict 
>>> OrderedDict.__repr__ is OrderedDict.__repr__ 
False 
>>> dict.__repr__ is dict.__repr__ 
True 
+1

파이썬 3.3에서는 True를 반환합니다. – HashSplat

+0

파이썬 2.7입니다. – Chameleon

+1

@JustinEngel : 파이썬 3은 언 바운드 메소드를 없애기 때문에 모든 메소드가 바인딩됩니다. Python 3에서'OrderedDict() .__ repr__ OrderedDict() .__ repr__'을 시도하면 똑같은 동작을 볼 수 있습니다. –

답변

56

파이썬 2 바운드 및 방법은 descriptor protocol 통한 수요에 생성되는 결합 ; OrderedDict.__repr__은 래핑 된 함수가 pure-Python function으로 구현되어 있으므로 이러한 메서드 개체입니다.

설명자 프로토콜은 __get__ method을 지원하는 개체에서 호출하므로 OrderedDict.__repr__에 액세스하려고 시도 할 때마다 __repr__.__get__()이 호출됩니다. 클래스 None (인스턴스 없음) 및 클래스 개체 자체가 전달됩니다. __get__ 메서드가 호출 될 때마다 메서드 개체가 발생하므로 is이 실패합니다. 같은 메소드 객체가 아닙니다.

dict.__repr__은 사용자 지정 Python 함수가 아니라 C 함수이며 __get__ 설명자 메서드 essentially just returns self when accessed on the class입니다. 속성에 액세스하는 것은 너무 is 작품, 같은 오브젝트 당신에게 각 시간을 제공 :

>>> dict.__repr__.__get__(None, dict) is dict.__repr__ # None means no instance 
True 

방법은 __func__ 속성 랩 기능을 참조 있고, 정체성을 테스트하기 위해 그것을 사용

>>> OrderedDict.__repr__ 
<unbound method OrderedDict.__repr__> 
>>> OrderedDict.__repr__.__func__ 
<function __repr__ at 0x102c2f1b8> 
>>> OrderedDict.__repr__.__func__.__get__(None, OrderedDict) 
<unbound method OrderedDict.__repr__> 
>>> OrderedDict.__repr__.__func__ is OrderedDict.__repr__.__func__ 
True 

파이썬 3 멀리 않습니다 언 바운드 메서드를 사용하면 function.__get__(None, classobj)은 함수 객체 자체를 반환합니다 (따라서 dict.__repr__처럼 동작합니다). 그러나 바인딩 된 메서드로 동일한 동작을 볼 수 있습니다.이 메서드는 인스턴스에서 검색됩니다.

+1

자신에게 이것을 증명하는 간단한 테스트로''__repr__'' 메소드를 사용하여 클래스를 만듭니다. __repr__ = lambda : x''이고''is'' 테스트는 실패합니다. 사실, 일반적으로''__repr__''을 무시하면''is''가 실패 할 것입니다. – aruisdante

+0

그리고 일반적으로 NO 클래스의 순수 파이썬 언 바운드 메소드는 "True"와 "is"를 비교합니다. – aruisdante

+0

@aruisdante : 음, 메소드 객체에 대한 참조 (둘 이상)를 만들 수 있습니다. 그런 다음 여전히'is'를 사용할 수 있습니다. 그러나 클래스에서 메소드를 가져 오는 것은 새로운 객체를 생성합니다. 왜냐하면'__get__' 함수는 새로운 객체를 생성하기 때문입니다. –

1

두 개의 OrderedDict.__repr__은 동일한 개체에 바인딩되지 않습니다. 시도한 경우 :

OrderedDict.__repr__ == OrderedDict.__repr__ 

이 값이 같음을 알 수 있습니다. 유저 정의 함수