2014-01-21 2 views
3

() 메소드에서 예외 (어쩌면 여러 번 또는 지연이있을 수 있음)가 발생하면 코드 객체를 다시 호출하려고합니다. 데코레이터를 사용하는 것은 매우 쉽지만, 필자의 동기는 때로는 별도의 함수로 추출하여 장식하고 싶지 않은 코드 단편을 반복하고 싶다는 것입니다.컨텍스트 관리자의 __exit __() 메서드 내에서 컨텍스트 개체 (코드 블록)에 액세스 할 수 있습니까?

x = 0 
with again(): 
    print x 
    x += 1 
    if x == 1: 
     raise Exception('I hate 1') 

및 예상 출력은 다음과 같습니다 :

class again(object): 
    def __enter__(self): 
     pass 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     if exc_type is not None: 
      ????  # Invoke the code object again 
      return True # eat exception 

그것은과 같이 사용합니다 :

0 
1 

내가 할 수있는 방법을 찾을 수 나는이 라인을 따라 뭔가를 찾고 있어요 코드 객체를 잡아라. 컨텍스트 관리자 속성 중 아무 것도 그것을 참조하는 것 같지 않습니다. (필자는 실제로 필요하지 않은 것 같습니다. 왜냐하면 일은 단지 전후에 할 일이기 때문입니다).

할 수 있습니까?

+0

'코드 개체'는 무엇을 의미합니까? –

+0

나는 이것이 가능하다는 것을 매우 의문스러워합니다. 주로 이것은 컨텍스트 관리자들이위한 것이 아니기 때문입니다. 언급했듯이, 파이썬의 처리 방법은 함수를 사용하는 것입니다 (아마도 데코레이터를 사용하는 것입니다). 당신이 묘사 한 것은 나에게 루비처럼 더 냄새가 난다 ... – mgilson

+0

컨텍스트 매니저는 자원 관리를위한 것이다. 코드 블록의 기능을 임의로 변경하는 "블록 데코레이터"로 설계된 적이 없었습니다. 이는 사용자가 찾고있는 것입니다. – user2357112

답변

5

with 블록이 별도의 코드 개체로 존재하지 않으므로 없습니다. this similar question을 참조하십시오. 이 경우 질문자는 역순으로 (코드 블록 내부에서 컨텍스트 관리자에 액세스) 시도했지만 this answer에서 설명한대로 with 블록은 별도의 범위가 아니므로 별개의 상태가 아닙니다.

당신은 예를 들어 이것을 볼 수 있습니다

import contextlib 
import dis 

@contextlib.contextmanager 
def silly(): 
    yield 

def foo(): 
    print "Hello" 
    with silly(): 
     print "Inside" 
    print "Goodbye" 

다음

>>> dis.dis(foo.__code__) 
    2   0 LOAD_CONST    1 (u'Hello') 
       3 PRINT_ITEM   
       4 PRINT_NEWLINE  

    3   5 LOAD_GLOBAL    0 (silly) 
       8 CALL_FUNCTION   0 
      11 SETUP_WITH    10 (to 24) 
      14 POP_TOP    

    4   15 LOAD_CONST    2 (u'Inside') 
      18 PRINT_ITEM   
      19 PRINT_NEWLINE  
      20 POP_BLOCK   
      21 LOAD_CONST    0 (None) 
     >> 24 WITH_CLEANUP   
      25 END_FINALLY   

    5   26 LOAD_CONST    3 (u'Goodbye') 
      29 PRINT_ITEM   
      30 PRINT_NEWLINE  
      31 LOAD_CONST    0 (None) 
      34 RETURN_VALUE 

당신은 with 블록의 코드가 다른 모든 것들과 함께 단지 함수의 코드 객체 내부에 있음을 알 수있다. 별도의 코드 객체로 존재하지 않으며 나머지 함수 코드와 구별되지 않습니다. 당신은 어떤 제정신 인 방법으로도 그것을 꺼낼 수 없습니다 (바이트 코드를 해킹하지 않고 말입니다).

관련 문제