Python的异常处理

目录
  1. 1. Python中常见的异常
  2. 2. 抛出异常
    1. 2.1 自动抛出
    2. 2.2 通过raise抛出
  3. 3. 捕获和处理异常
  4. 4. 定义新的异常

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

与Python中所有其它东西一样,异常是一个对象。它由Python的raise语句产生,产生之后它会影响程序的正常执行过程,程序不会继续执行raise之后的语句,而是搜索当前的调用链来寻找可以处理该异常的异常处理程序。

1. Python中常见的异常

下面列出Python中的部分异常:

BaseException
    KeyboardInterrupt
    Exception
        ArithmeticError
        ZeroDivisionError
        AttributeError
        EnvironmentError
            IOError
            OSError
                WindowsError (Windows) 
                VMSError (VMS) 
        LookupError
            IndexError
        NameError
            UnboundLocalError
        ReferenceError
        RuntimeError
            NotImplementedError
        SyntaxError
            IndentationError
                TabError
        TypeError
        ValueError
        Warning
            DeprecationWarning
            SyntaxWarning
            UserWarning
            FutureWarning
            ImportWarning

建议任何用户自定义的异常应该以Exception为基类,而不是BaseException,是因为当有如下的代码段时:

1
2
3
4
try:
# do stuff
except Exception:
# handle exceptions

用户可以通过Ctrl-C终止try部分的代码执行,而不会触发异常处理程序,因为KeyboardInterrupt异常并不是Exception的子类。

2. 抛出异常

2.1 自动抛出

很多异常由Python的built-in函数自动抛出,如除数为0等异常。

2.2 通过raise抛出

也可以通过raise语句抛出:

raise exception(args)

语句中exception是异常的类型(例如,NameError);args是一个异常参数值。该参数是可选的,如果不提供,异常的参数是”None”。例如:

>>> raise IndexError("Just kidding")
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
    raise IndexError("Just kidding")
IndexError: Just kidding

3. 捕获和处理异常

Python中异常的捕获和处理一般形式如下:

try:
    body
except exception_type1 as var1:
    exception_code1
except exception_type2 as var2:
    exception_code2
    .
    .
    .
except:
    default_exception_code
else:
    else_body
finally:
    finally_body
  1. 异常处理是以 try 开始。
  2. 当异常发生时按照一定规则执行except块,可以存在多个except块。
  3. 如果没有匹配的except块,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
  4. 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话)。
  5. 可选的finally块,无论如何都会执行,通常用于清理工作。

except 块的选择:

  • 判断 try 块中抛出的异常实例,是否是exception_type1的实例。
  • 如果是,执行异常处理语句,可选的as var1,把抛出的异常实例赋值给var1。
  • 如果不是,继续往下判断是否是exception_type2的实例。
  • 单独的except捕获任意异常。
  • 需要注意except的顺序,子类异常在前,父类异常在后。

4. 定义新的异常

当一个类继承自Exception及其派生类,那么就是自定义的异常。例如:

class MyError(Exception):
    pass

你可以像其它异常一样抛出、捕获并处理自定义的异常:

>>> raise MyError("Some information about what went wrong")
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
    raise MyError("Some information about what went wrong")
MyError: Some information about what went wrong

如果在抛出异常是提供了多个参数,它将以元组的形式传递到异常处理程序,可以通过args变量访问它们:

try:
    raise MyError("Some information", "my_filename", 3)
except MyError as error:
    print("Situation: problem {0} with file {1}: {2}".format( 
        (error.args[2], error.args[1], error.args[0]))