Python的异常处理机制

在程序开发过程中,难免出现这样那样的错误,有些使我们的逻辑导致的错误,也就是我们常说的Bug, 这些都是很容易修复的。有些是我们无法预测的,比如当我们写入文件的时候,文件被删除了,或者磁盘空间满了,在比如网络传输数据,网络突然断了。这类的错误我们称之为异常。

和其他很多语言一样,Python也有自己的异常处理机制。

try...except...finally...

Python的异常完整的结果是这样子的

try:
    # 主代码块
    pass
except KeyError,e:
    # 异常时,执行该块
    pass
else:
    # 主代码块执行完,执行该块
    pass
finally:
    # 无论异常与否,最终执行该块
    pass

我们先来看一个例子,了解一下基本流程

try:
    print('try...')
    r = 10 / 0
    print('result:', r)
except ZeroDivisionError as e:
    print(e)
finally:
    pass
print('END')

我们都知道0不能做除数,在程序中,一旦遇到除数为零的情况,任何语言都会出现异常。

执行结果

try...
except: division by zero
finally...
END

从执行结果来看,当程序运行到10 / 0的时候,遇到了异常,所以异常被捕获到,但是后面的语句print('result:', r)没有执行,但是并影响程序的继续运行,try块外面的部分是不受到影响的得以继续运行。所以print('END')正常输出了。另外except表示匹配后面的错误类型,错误ZeroDivisionError就是表示除数为零的错误。所以被except ZeroDivisionError as e:匹配到,所以print(e)as e表示将错误信息赋值给一个变量e。这个变量名可以随意。

从语法上和if语句很像,可以匹配多个条件,也就是可以有多个except,匹配多个异常。最后的finally表示前面的错误都没有匹配到要执行的块。

另外Python的异常捕获可以跨层捕获,比如我们定义了一个函数,函数里面出现了异常,我们可以在调用这个函数的代码块中捕获

def foo():
return 10 / 0

try:
    foo()
except ZeroDivisionError as e:
    print(e)

执行结果

division by zero

常见异常

Python内置了一些常见异常

`AttributeError`:试图访问一个对象没有的成员
`IOError`:输入/输出异常;基本上是无法打开文件
`ImportError`:无法引入模块或包;基本上是路径问题或名称错误
`IndentationError`:语法错误(的子类);代码没有正确对齐
`IndexError`:下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
`KeyError`:试图访问字典里不存在的键
`KeyboardInterrupt`:`Ctrl+C`被按下,也就是试图强制退出程序
`NameError`:使用一个还未被赋予对象的变量
`SyntaxError`:Python代码非法,代码不能编译,也就是语法错误
`TypeError`:传入对象类型与要求的不符合
`UnboundLocalError`:试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
`ValueError`:传入一个调用者不期望的值,即使值的类型是正确的
`Exception`:代表所有异常(当然不是所有异常都能被捕获至少`KeyboardInterrupt`就不能被它捕获)

几个创建异常例子

dic = ["wupeiqi", 'alex']
try:
    dic[10]
except IndexError, e:
    print e

dic = {'k1':'v1'}
try:
    dic['k20']
except KeyError, e:
    print e

s1 = 'hello'

try:
    int(s1)
except ValueError, e:
    print e

主动抛出异常

有的时候我们出于某种目的,比如强制让他传一个什么样类型的数据。需要主动抛出异常,Python中我们通过raise关键字

def foo(s):
    if not isinstance(s, int):
        raise ValueError('这里需要传入一个整数类型')
    else:
        print(int(s))

try:
    foo(12)
    foo('hello')
except ValueError as e:
    print(e)

执行结果

12
这里需要传入一个整数类型

当我们传入的是一个整数的时候,没有问题,当我传入一个字符串的额时候由于if not isinstance(s, int):判断出来参数不是整数类型,所以主动通过raise ValueError('这里需要传入一个整数类型')抛出了异常。

自定义异常

除了Python自带的异常以外,我们也可以自定义一个异常。定义一个异常就是定义一个类,继承自Exception

class customException(Exception):
    def __init__(self, msg):
        self.message = msg

    def __str__(self):
        return self.message


try:
    raise customException('这是自定义的异常')
except customException as e:
    print(e)

执行结果

这是自定义的异常

猜你喜欢

转载自blog.csdn.net/c123_sensing/article/details/81634728