2010-01-11 27 views
19

herhangi bir yükseltilmiş nesneyi (yani, Exception'u genişletmeyen bir tür) nasıl yakalayabildiğimi merak ediyorum ve yine de ona bir başvuru olsun.Python'da bir istisna nasıl yakalanır ve istisna ile ilgili bir referans alırsınız.

Jython'u kullanırken bunu yapma arzusuna rastladım. Java yöntemini ararken bu yöntem bir istisna tutarsa, bu Python'un Exception sınıfını uzatmaz, bu nedenle böyle bir blok yakalamak olmaz:

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

Bunu yapabilirim, ama sonra hiçbir erişebilir yükseltilen istisna nesnesi.

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 
Java istisna tipini ithal ve açıkça yakalayarak bu çözebilir, ancak bu imkansız/zor jenerik istisna işleme sarmalayıcıları/dekoratörler yazmak için yapar

.

Bazı keyfi istisnaları yakalamanın ve hala except bloğundaki referansa ulaşmanın bir yolu var mı?

numaralı belgeyi not etmeliyim ki, yalnızca Jython projeleriyle değil, Python projeleriyle kullanabileceğim istisna işleme dekoratörünü umuyorum. java.lang.Exception'u içe aktarmaktan kaçınmak istiyorum çünkü bu sadece Jython-only. Örneğin, bunun gibi bir şey yapabileceğimi düşünüyorum (ama denemedim), ama eğer yapabilirsem kaçınmak isterim.

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 kaynaklanıyor en azından bu istisnaları mı yakalayacak? – Seth

cevap

33

sys modülünü kullanarak istisnalara başvurabilirsiniz. sys.exc_info, türün, örnek ve geri izlemenin bir dizisidir. Adam gibi bir yığın izleme almak için öğrenmek istedim çünkü

import sys 

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

ah, bir deneyin, teşekkürler! –

5

Sadece ilgilenen herkes için ... Ben zaman test şeyler biraz geçirdi Python İstisna (temel sınıftır BaseException aslında,) ister veya java.lang.Throwable (java taban sınıfı özel durum, hata, vb) atılır ... Bu kod, tüm satır sayısı refs doğru bir şekilde yakalamak için nasıl gösterir. bu bir bu catch-Atılabil blok her zaman deneyin-dışında, yazmak zorunda kalmamak için def önce benzer yöntemler (öz) çalıştırın ve bir dekoratör yazma düşünebilir sonra

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()) 

.. . özellikle:

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, ben bulduk o size Jython komut dosyasına bu ithalat eklerseniz: geleneksel Python İstisna işleyicisi

from java.lang import Exception 

ve sadece kullanın:

except Exception, e: 

o hem Python istisnalar ve Java istisnalar