2011-08-01 4 views
2

PEP-343은이 상황에서 type()을 사용하는 이유는 무엇입니까?메서드 호출에 type() 사용

mgr = (EXPR) 
    exit = type(mgr).__exit__ # Not calling it yet 
    value = type(mgr).__enter__(mgr) 

우리는 단지뿐만 아니라 exit = mgr.__exit__value = mgr.__enter__()를 사용할 수 없습니다? 나에게 더 단순 해 보이지만 나는 뭔가를 놓치고 있다고 생각한다.

답변

5

PEP 은 유형의 속성 대신 인스턴스 자체의 속성을 사용할 수 있지만, 이는 Python의 특수 메소드를 사용하는 것과는 대조적입니다. 예를 들어

a + b 

type(a).__add__(a, b) 

하지로 변환되어 다음의 예에 의해 도시 된 바와 같이

a.__add__(b) 

: 그래서

>>> class MyInt(int): 
...  pass 
... 
>>> a = MyInt(3) 
>>> b = MyInt(4) 
>>> a + b 
7 
>>> a.__add__ = lambda self, other: 42 
>>> a + b 
7 

, t o 나머지 파이썬과 일치하도록하려면 __enter__()__exit__()의 특수 메소드를 먼저 유형 사전에서 찾아야한다.

+0

좋습니다. 그래서 누군가가 __dict__ 인스턴스를 변경하면 우리는 여전히 원래의 함수를 호출합니다. 그것에 대해 생각조차하지 않았다 - 내가하고 싶은 상황을 아직 찾지 못했다.)하지만 누군가가 그랬다면 이상한 행동으로 이어질 수있다. – Voo

+1

@Voo : 컨벤션의 이론적 근거는 이상한 행동을 피하는 것이 아닙니다. 즉, 'a' 인스턴스의'__add __()'메소드를 on-the-fly 타입으로 오버라이드하여 덮어 쓸 수 있습니다 :'a. __class__ = type ("", (type (a),), { "__add__": 람다 셀프, other : 42})'. 대신,이 동작에 대한 이론적 근거는 성능입니다. 특별한 메소드는 타입의'__dict__'에서 찾지 않습니다. 내부 형식 데이터 구조는 특수 메서드에 대한 포인터를위한 특수 필드를 제공하므로 훨씬 빠르게 조회 할 수 있습니다 (http://docs.python.org/extending/newtypes.html#the-basics 참조). –

+0

PyMethodDef 배열을 의미합니까? 여전히 검색해야하지만 (더 빠를 수도 있습니다)? 아니면 우리가 모든 특수 메소드에 대해 하나의 일반적인 메소드를 사용하도록하기 위해 이렇게했습니다. tp_iternext와 같은 일부 메소드는 PyTypeObject에서 선언 되었기 때문에 이익을 얻습니다. – Voo

2

위의 구조는 mgr 객체의 유형 (클래스)의 언 바운드 방법, 그렇지 않으면 mgr DICT가 acessed되어 얻고 당신은 바인딩 된 메서드를 얻을.

관련 문제