2013-03-25 4 views
3

저는 항상 파이썬 인터프리터에서 x.__class__type(x)의 값이 동일하다고 생각했습니다. 그러나 우리는 (또한 PyPy 2.0b1를 파이썬 2.7, 3.3 등) 다음을 수행하는 경우 :weakref가있는 타입의 동작 - 이해할 수 없음

>>> import weakref 
>>> x = set() 
>>> y = weakref.proxy(x) 
>>> x.__class__, isinstance(x, set), type(x) 
(<type 'set'>, True, <type 'set'>) 
>>> y.__class__, isinstance(y, set), type(y) 
(<type 'set'>, True, <type 'weakproxy'>) 

우리가 y.__class__ 내가 weakref.proxy 그냥 변장에 대한 속성을 대체한다고 가정 (weakref.proxy을위한 포장 유형에 해당하는 것을 볼 수 있습니다). 심지어 isinstanceyset으로 식별합니다.

그러나 type은 "true"유형 - weakproxy을 보여줍니다. 따라서 type은 인수 유형을 식별하는 데 __class__ 속성을 사용하지 않습니다. 그렇습니까? 이를 위해 좀 더 안정적인 소스를 사용합니까? 그렇다면 직접 액세스 할 수 있습니까?

답변

4

x.__class__type(x)은 동일하지 않습니다. type(x)typeobject.c을 루팅하고 있으며 실제 유형 ob_type을 반환합니다.

/* 특별한 경우 : 유형 (X)를 호출한다 X-> ob_type * x.__class__ 단지 속성 조회이다/

동안. 속성 조회가 재정의되지 않은 한 object.__getattribute__(x, '__class__')과 같습니다.
object'__class__'은 데이터 설명 자이며 typeobject.c에도 정의되어 있습니다. 그 getterob_type을 반환합니다. 따라서 대부분의 경우 x.__class__type(x)이 같은 결과를 반환합니다. 즉 _PyWeakref_ProxyType

그러나 weakproxy은 의도적으로 proxy_getattr 자신을 정의했다. 따라서 y.__class__은 (는) type(y)과 (와) 일치하지 않습니다.

다음 실험에서 우리는 같은 효과를 얻을 수 있습니다.

class A(object): 
    pass 

class C(object): 
    def __getattribute__(self, name): 
     if name == '__class__': 
      return A 
     return object.__getattribute__(self, name) 


>>> c = C() 
>>> c.__class__ 
<class '__main__.A'> 
>>> type(c) 
<class '__main__.C'> 

더욱이, isinstance(c, A)isinstance(c, C)이 예에서 모두 사실이다. isinstance부터 ob_type의 동등성을 먼저 확인합니다.

+0

답장을 보내 주셔서 감사합니다. 'isinstance'정보. 먼저 ob_type을 확인한 다음 equals가 아닌 경우 __class__를 검사합니까? –

+1

@IvanYurchenko, 대략, 네, 처음으로'ob_type','__class__'. 사실, 그 사이에는 특별한 훅 ([__instancecheck__]) (http://docs.python.org/2/reference/datamodel.html?highlight=__instancecheck__#class.__instancecheck__)이 있습니다. – nymk

+0

고맙습니다, @nymk. –

관련 문제