2017-01-15 2 views
0

, 나는 다음과 같은 코드가 작동하지 않는 것으로 나타났습니다 :왜`with`가 클래스가 아닌`__enter__`을 사용합니까? 런타임에 컨텍스트 매니저 패치 실험을하는 동안 내가 예상대로

class B: 
    def __enter__(self): 
     print('normal') 
    def __exit__(self, *stuff): 
     pass 

    def modify(self, x): 
     def other(self): 
      print('not normal: ', x) 
     self.__enter__ = other.__get__(self, type(self)) 

def main(): 
    b = B() 
    b.__enter__() 
    b.modify('hi') 
    b.__enter__() 
    with b: 
     print('in with') 
    b.__enter__() 

if __name__ == '__main__': 
    main() 

실행이 인쇄 :

normal 
not normal: hi 
normal 
in with 
not normal: hi 

동안 main의 첫 번째 부분 , __enter__에 대한 명시 적 호출이 예상대로 작동합니다 (이 올바르게 수정 됨). with- 구문은이를 무시한 것 같습니다.

일부 검색을 수행 한 결과, PEP 343에 따라 동작이 설명 된 것으로 나타났습니다. 즉, with mgr: ...의 번역은 내부적으로 제가 위에서하고있는 것처럼, 대신에 직접 메서드 호출의

type(mgr).__enter__(mgr) 

같은 것을 사용합니다.

그리고 그 이유가 궁금합니다. 저 같은 사람들이 어지럽게 흩어 지거나, 더 깊은 이유가있는 것을 막는 것입니까?

답변

0

special method lookup이 언어 설명에 정의되어 있습니다. 기본적으로이 종류의 조회 (type(obj).__method__(obj) 사용)는 모든 "마법 방법"에서 발생합니다. 두 가지 이유가 주어진다 :

  • 성능 최적화
  • 는 작품에 경우 특별한 조회, type(int).__hash__로하지 같은 일 것 같은 (종류에 int.__hash__을 연기 즉 때, 제대로이 변형에있다
  • 수있는 우리는 정말로 원한다).
+0

나는 두 번째 주장을 완전히 이해하지 못했을 것이다. 당신이 원하면, 그것을 향상 시키십시오. – phg

관련 문제