python: How do I know what type of exception occurred?

后端 未结 15 1913
情书的邮戳
情书的邮戳 2020-11-29 14:56

I have a function called by the main program:

try:
    someFunction()
except:
    print \"exception happened!\"

but in the middle of the ex

相关标签:
15条回答
  • 2020-11-29 15:21

    Most answers point to except (…) as (…): syntax (rightly so) but at the same time nobody wants to talk about an elephant in the room, where the elephant is sys.exc_info() function. From the documentation of sys module (emphasis mine):

    This function returns a tuple of three values that give information about the exception that is currently being handled.
    (…)
    If no exception is being handled anywhere on the stack, a tuple containing three None values is returned. Otherwise, the values returned are (type, value, traceback). Their meaning is: type gets the type of the exception being handled (a subclass of BaseException); value gets the exception instance (an instance of the exception type); traceback gets a traceback object (see the Reference Manual) which encapsulates the call stack at the point where the exception originally occurred.

    I think the sys.exc_info() could be treated as the most direct answer to the original question of How do I know what type of exception occurred?

    0 讨论(0)
  • 2020-11-29 15:23

    The actual exception can be captured in the following way:

    try:
        i = 1/0
    except Exception as e:
        print e
    

    You can learn more about exceptions from The Python Tutorial.

    0 讨论(0)
  • 2020-11-29 15:24

    Get the name of the class that exception object belongs:

    e.__class__.__name__
    

    and using print_exc() function will also print stack trace which is essential info for any error message.

    Like this:

    from traceback import print_exc
    
    class CustomException(Exception): pass
    
    try:
        raise CustomException("hi")
    except Exception, e:
        print 'type is:', e.__class__.__name__
        print_exc()
        # print "exception happened!"
    

    You will get output like this:

    type is: CustomException
    Traceback (most recent call last):
      File "exc.py", line 7, in <module>
        raise CustomException("hi")
    CustomException: hi
    

    And after print and analysis, the code can decide not to handle exception and just execute raise:

    from traceback import print_exc
    
    class CustomException(Exception): pass
    
    def calculate():
        raise CustomException("hi")
    
    try:
        calculate()
    except Exception, e:
        if e.__class__ == CustomException:
            print 'special case of', e.__class__.__name__, 'not interfering'
            raise
        print "handling exception"
    

    Output:

    special case of CustomException not interfering
    

    And interpreter prints exception:

    Traceback (most recent call last):
      File "test.py", line 9, in <module>
        calculate()
      File "test.py", line 6, in calculate
        raise CustomException("hi")
    __main__.CustomException: hi
    

    After raise original exception continues to propagate further up the call stack. (Beware of possible pitfall) If you raise new exception it caries new (shorter) stack trace.

    from traceback import print_exc
    
    class CustomException(Exception): pass
    
    def calculate():
        raise CustomException("hi")
    
    try:
        calculate()
    except Exception, e:
        if e.__class__ == CustomException:
            print 'special case of', e.__class__.__name__, 'not interfering'
            #raise CustomException(e.message)
            raise e
        print "handling exception"
    

    Output:

    special case of CustomException not interfering
    Traceback (most recent call last):
      File "test.py", line 13, in <module>
        raise CustomException(e.message)
    __main__.CustomException: hi    
    

    Notice how traceback does not include calculate() function from line 9 which is the origin of original exception e.

    0 讨论(0)
提交回复
热议问题