2009-06-29 4 views
35

type(obj)obj.__class__의 차이점은 무엇입니까? 가능성이 있습니까 type(obj) is not obj.__class__?유형 (obj)과 obj .__ class__의 차이점

다른 매개 변수와 동일한 유형의 기본값 1을 사용하여 제공된 객체에서 일반적으로 작동하는 함수를 작성하고 싶습니다. 아래의 # 1 또는 # 2의 변형은 올바른 일을 할 것입니까?

def f(a, b=None): 
    if b is None: 
    b = type(a)(1) # #1 
    b = a.__class__(1) # #2 

답변

12

type(obj)type.__class__ 오래된 스타일 클래스에 대해 동일하게 동작하지 않습니다

>>> class a(object): 
...  pass 
... 
>>> class b(a): 
...  pass 
... 
>>> class c: 
...  pass 
... 
>>> ai=a() 
>>> bi=b() 
>>> ci=c() 
>>> type(ai) is ai.__class__ 
True 
>>> type(bi) is bi.__class__ 
True 
>>> type(ci) is ci.__class__ 
False 
+7

가장 큰 아이러니는 yairchu의 의견이 이제 형식을 바꾼 이후 같은 문제가 있습니다. : P –

+10

그들이 어떻게 다르게 행동하는지, 어쩌면 왜 * 왜 * 표시할지 상처를주지는 않습니다. * 언제 그들이 다르게 행동하는지 말하는 것은 올바른 경우라도 게으른 대답을합니다. – MestreLion

+1

이것은 파이썬 2에서만 중요한 문제입니다. 파이썬 3에서는이 세 표현식이 모두 참입니다. – Bob

30

이전 스타일 클래스가 문제입니다, 한숨 :

>>> class old: pass 
... 
>>> x=old() 
>>> type(x) 
<type 'instance'> 
>>> x.__class__ 
<class __main__.old at 0x6a150> 
>>> 

아니 문제를 파이썬 3에서 모든 클래스는 새로운 스타일은 지금부터 ;-). 이 암시 적으로 또는 명시 적으로 (object 등 다양한 내장 유형과 같은 dict, list, set, ...) 또는 다른 새로운 스타일의 클래스에서 상속하는 경우 파이썬 2에서

는 클래스는 새로운 스타일 아니라 __metaclass__type으로 설정하십시오.

+3

파이썬 3 시간입니다 * 사용해야합니까? –

+2

코드가 Alex가 설명한 모범 사례를 따르는 경우 'type()'이 좋습니다. 파이썬 3에서는 항상 모범 사례를 따르므로 파이썬 3에서 type()을 사용하십시오. –

+0

@AaronHall 파이썬을 쓰고있는 경우'type()'을 사용하는 것이'__class__ '보다 선호된다고 가정하는 것이 맞겠습니까? 2 코드 어디 새로운 스타일의 클래스의 인스턴스와 함께 호출됩니다 알아? – kasperd

30

이것은 오래된 질문이지만 답변의 아무도는 말할 것 같다. 일반적인 경우에는, 새로운 스타일 클래스 type(instance)instance.__class__ 대해 다른 값을 가질 수 있도록 수있다 :

class ClassA(object): 
    def display(self): 
     print("ClassA") 

class ClassB(object): 
    __class__ = ClassA 

    def display(self): 
     print("ClassB") 

instance = ClassB() 

print(type(instance)) 
print(instance.__class__) 
instance.display() 

출력 : ClassB__class__ 재정의된다

<class '__main__.ClassB'> 
<class '__main__.ClassA'> 
ClassB 

이유는 그러나 개체의 내부 형식 필드는 변경되지 않습니다. type(instance)은 해당 유형 필드에서 직접 읽으므로 올바른 값을 반환하는 반면 instance.__class__은 내부 유형 필드를 읽는 Python에서 제공 한 원래 설명자를 대체하는 새 설명자를 참조합니다. 해당 내부 형식 필드를 읽는 대신 하드 코딩 된 값을 반환합니다.

+10

_Caveat lector_ : 이것은 __class__를 무시하는 이유의 예입니다. '__class__'를 사용하는 줄을 어지럽게 만들 수 있습니다. –

+0

'OBJ .__ class__'에 대한 요청을 차단하지만'type (OBJ)'에 대한 요청을 차단하는'__getattribute__'의 영향을받습니다. – kdb