2016-07-12 5 views
1

스택이 프로그램의 최상위 레벨로 올라가는 동안 예외가 여러 번 catch되는 것을 방지 할 수있는 방법이 있습니까? 여기 예외를 여러 번 잡는 것을 방지하는 방법

는 현상을 설명 매우 간단한 코드 예제입니다

def try_except_block(smthg): 
    try: 
    smthg.run() 
    except Exception as e: 
    print("WRONG") 
    raise e 

def re_call(): 
    f2 = Foo(True) # will throw an exception 
    try_except_block(f2) 

class Foo: 
    def __init__(self, t): 
    self.throw = t 
    def run(self): 
    if self.throw: 
     raise KeyError 
    else: 
     re_call() 

if __name__ == '__main__': 
    f = Foo(False) # won't throw an exception 
    try_except_block(f) 

출력 : 내가 좋아하는 것

WRONG 
WRONG 
Traceback (most recent call last): 
    File "exception_loosing_args.py", line 26, in <module> 
    try_except_block(f) 
    File "exception_loosing_args.py", line 9, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 22, in run 
    re_call() 
    File "exception_loosing_args.py", line 13, in re_call 
    try_except_block(f2) 
    File "exception_loosing_args.py", line 9, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 20, in run 
    raise KeyError 
KeyError 

는 "WRONG"한 번 인쇄 할 수 있습니다.

내 소프트웨어에서 try_except_block 함수는 객체에 래핑됩니다.이 객체의 속성을 설정하여 "이미 방문한"것으로 예외 구문을 표시 할 수 있습니다. 이 아이디어에 의해 이끌어 낼 수있는 부작용 때문에이 아이디어가 마음에 들지 않습니다. 다른 것이 있습니까?

나는 (클래스 속성이 전역 변수 flag에 의해 에뮬레이트) 생각했던 것의

exemple :

flag = False 

def try_except_block(smthg): 
    global flag 
    try: 
    smthg.run() 
    except Exception as e: 
    if not flag: 
     print("WRONG") 
     flag = True 
    raise e 

def re_call(): 
    f2 = Foo(True) # will throw an exception 
    try_except_block(f2) 

class Foo: 
    def __init__(self, t): 
    self.throw = t 
    def run(self): 
    if self.throw: 
     raise KeyError 
    else: 
     re_call() 

if __name__ == '__main__': 
    f = Foo(False) # won't throw an exception 
    try_except_block(f) 

출력 : 코드가하는 이유

WRONG 
Traceback (most recent call last): 
    File "exception_loosing_args.py", line 28, in <module> 
    try_except_block(f) 
    File "exception_loosing_args.py", line 11, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 24, in run 
    re_call() 
    File "exception_loosing_args.py", line 15, in re_call 
    try_except_block(f2) 
    File "exception_loosing_args.py", line 11, in try_except_block 
    raise e 
    File "exception_loosing_args.py", line 6, in try_except_block 
    smthg.run() 
    File "exception_loosing_args.py", line 22, in run 
    raise KeyError 
KeyError 
+0

'except'에서 예외를 다시 발생시키지 않으면 전파가 중단됩니다 ... –

+0

동작은 논리적 인 용어로 정확합니다. 두 개의 중첩 된 try..except가 있습니다. 블록 모두 예외를 포착하고 다시 발생시켜 메시지를 두 번 트리거합니다. 아마도 덜 복잡하고 재귀적인 논리를 사용하는 것이 최선의 "수정"일 것입니다 ...? – deceze

+0

감사합니다. Jon Clements : 다른 목적으로 프로그램의 최상위 레벨을 잡으려면 예외가 필요합니다. 나는 예외를 전파해야한다 : 여기서 딜레마가있다. @deceze : 할 수 없습니다. 이 코드는 그래프의 노드를 재귀 적으로 방문하는 데 사용됩니다. –

답변

2

내가 완전히 이해하지 않는다 그것은 무엇입니까,하지만 당신이 할 수있는 일은 입니다. 이미 전역 플래그를 설정하는 대신 예외 객체를 이미 표시된 것으로 표시하는 것입니다. 그래서 같이 :

def try_except_block(smthg): 
    try: 
     smthg.run() 
    except Exception as e: 
     if not hasattr(e, "teb_already_seen"): 
      setattr(e, "teb_already_seen", True) 
      print("WRONG") 
     raise e 

그런 식으로, try_except_block 수행 여분 처리 한 번만 아마 당신이 원하는 예외 객체, 당을 발생합니다.

+0

이것은 정확히 내가 염두에 두었던 부작용을 막고 싶었습니다. 고맙습니다 –

관련 문제