2010-01-11 5 views
19

제기 된 객체 (즉, Exception을 확장하지 않는 유형)를 어떻게 잡을 수 있는지 궁금합니다. 여전히 그것에 대한 참조를 얻습니다.파이썬에서 예외를 잡아 내고 형식을 알지 못하고 예외에 대한 참조를 얻는 방법?

나는 자이 썬을 사용할 때 이렇게하기를 바랬다. Java 메소드를 호출 할 때 그 메소드가 예외가 발생하면, 그것은 파이썬의 Exception 클래스를 확장하지 않으므로이 같은 블록은 그것을 잡을되지 않습니다

try: 
    # some call to a java lib that raises an exception here 
except Exception, e: 
    # will never be entered 

내가이 작업을 수행 할 수 있습니다,하지만 난에 액세스 할 수 없습니다 발생한 예외 객체

try: 
    # some call to a java lib that raises an exception here 
except: 
    # will enter here, but there's no reference to the exception that was raised 
내가 자바 예외 유형을 가져 명시 적으로 그것을 잡는하여이 문제를 해결 할 수 있지만,이 것이 불가능/어려운 일반적인 예외 처리 래퍼/장식을 작성할 수 있습니다

.

임의의 예외를 잡아 내고 여전히 except 블록에 대한 참조를 얻을 수있는 방법이 있습니까?

자이 썬 프로젝트뿐만 아니라 파이썬 프로젝트에서도 사용할 수 있도록 예외 처리 데코레이터를 사용하고 싶습니다.에 주목해야합니다. java.lang.Exception을 가져 오는 것을 피하고 싶습니다. Jython 전용으로 만들기 때문입니다. 예를 들어, 나는이 같은 것을 할 수 있다고 생각한다. (그러나 나는 그것을 시도하지 않았다.) 할 수 있다면 나는 그것을 피하고 싶다.

try: 
    # some function that may be running jython and may raise a java exception 
except (Exception, java.lang.Exception), e: 
    # I imagine this would work, but it makes the code jython-only 
+0

BaseException에서 파생 적어도 이러한 예외를 수행 잡을 것인가? – Seth

답변

33

sys 모듈을 사용하여 예외를 참조 할 수 있습니다. sys.exc_info은 유형, 인스턴스 및 추적의 튜플입니다. 나는 적절한 스택 추적을 얻을하는 방법을 알아 싶었 기 때문에

import sys 

try: 
    # some call to a java lib that raises an exception here 
except: 
    instance = sys.exc_info()[1] 
+0

아, 시도해 볼게, 고마워! –

5

그냥 관심있는 사람들을 위해 ... 나는 시간 테스트 물건의 비트를 보냈다 파이썬 예외 (기본 클래스입니다 BaseException 사실,) 여부 또는 Exception, Error 등의 java.lang.Throwable (Java 기본 클래스)이 throw됩니다.이 코드는 모든 행 번호 심판을 올바르게 캐치하는 방법을 보여줍니다. 이 사람이이 캐치 - 더 -의 Throwable 블록마다 시도-제외를 작성하지 않도록 데프 앞에 유사한 방법을 (자기)를 실행하고 데코레이터를 작성하는 생각 후

import sys 
import traceback 
import java 

print "hello world" 

def custom_hook(type, exc, tb): 
    if isinstance(sys.exc_info()[ 1 ], java.lang.Throwable): 
    sys.stderr.write("AS JAVA:\n") 
    sys.exc_info()[ 1 ].printStackTrace() # java part 
    else: 
    sys.stderr.write("NO JAVA TRACE:\n") 
    sys.stderr.write("AS PYTHON:\n") 
    traceback.print_exc() 

# useful for custom exception handling! 
sys.excepthook = custom_hook 

def handle_exc(): 
# generate either a java.lang.Throwable (uncomment the next line and comment out "a = 16/0" 
# java.lang.String(None) 
# OR... a python-style BaseException: 
    a = 16/0 

class Task(java.lang.Runnable): 
    def run(self): 
    # NB the problem with all this stuff is that the Java stack trace shows 
    # a java.lang.Throwable occurring at the last line of this code block... 
# print "lots of stuff first" 
# print "lots 2" 
# handle_exc() 
# print "lots 3" 
# print "lots of stuff after" 

    try: 
     print "lots of stuff first" 
     print "lots 2" 
     handle_exc() 
     print "lots 3" 
     print "lots of stuff after" 
    # NB do not catch both (Python) BaseException and java.lang.Throwable... 
# except (BaseException, java.lang.Throwable), e: 
    # the above means that the line no. in handle_exc is not shown when a BaseException 
    # is thrown... 
    except java.lang.Throwable, t: 
     tb = sys.exc_info()[ 2 ] 
     sys.stderr.write("java.lang.Throwable thrown at: %s\n" % tb.tb_lineno) 
     raise t 

java.awt.EventQueue.invokeAndWait(Task()) 

.. . 특별히 :

def throw_trap(function): 
    def wrapper(*args, **kvargs): 
    try: 
     return function(*args, **kvargs) 
    except java.lang.Throwable, t: 
     tb = sys.exc_info()[ 2 ] 
     while(tb): 
     sys.stderr.write("thrown at: %s\n" % tb.tb_lineno) 
     tb = tb.tb_next 
     raise t 
    return wrapper 



def handle_exc(): 
    java.lang.String(None) 
# a = 16/0 


class Task(java.lang.Runnable): 
    @throw_trap 
    def run(self): 
    print "lots of stuff first" 
    print "lots 2" 
    handle_exc() 
    print "lots 3" 
    print "lots of stuff after" 

java.awt.EventQueue.invokeAndWait(Task()) 
8

FWIW, 내가 찾은 당신은 당신의 자이 썬 스크립트에이 가져 오기를 추가하는 경우 : 기존의 파이썬 예외 핸들러

from java.lang import Exception 

그냥 사용

except Exception, e: 

모두 파이썬 예외 Java 예외

관련 문제