代码之家  ›  专栏  ›  技术社区  ›  TM. Randy Simon

如何在不知道异常类型的情况下捕获python中的异常并获取对该异常的引用?

  •  19
  • TM. Randy Simon  · 技术社区  · 14 年前

    我想知道我怎样才能赶上 任何 凸起对象(即不扩展的类型 Exception ),并且仍然可以获得对它的引用。

    我在使用Jython时遇到了这样的愿望。调用Java方法时,如果该方法引发异常,它将不会扩展Python的

    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
    

    我可以通过导入Java异常类型并显式捕获它来解决这个问题,但这使得编写通用异常处理包装器/装饰器变得困难/不可能。

    是否有一种方法可以捕获某些任意异常,并在 except

    我希望我正在制作的异常处理装饰器能够用于Python项目,而不仅仅是Jython项目。我想避免进口 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
    
    3 回复  |  直到 14 年前
        1
  •  36
  •   Brian McKenna    14 年前

    您可以使用 sys 模块。 sys.exc_info 是类型、实例和回溯的元组。

    import sys
    
    try:
        # some call to a java lib that raises an exception here
    except:
        instance = sys.exc_info()[1]
    
        2
  •  9
  •   Adrian Mehlig    10 年前

    FWIW,我发现如果将此导入添加到Jython脚本中:

    from java.lang import Exception
    

    except Exception, e:
    

    它会抓住你的 二者都 Python异常

        3
  •  5
  •   mike rodent    11 年前

    只为任何有兴趣的人。。。我花了一点时间测试这些东西,因为我想知道如何获得正确的堆栈跟踪,不管是抛出Python异常(实际上是基类BaseException)还是java.lang.Throwable(异常、错误等的java基类)。。。此代码说明了如何正确捕获所有行号引用。

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