首页 > 编程笔记

Python try except语句捕获异常

try…except 语句用于处理 Python 所输出的异常,其语法格式如下:
try:
    <语句>
except [<异常的名称> [, <异常类的实例变量名称>]]:
    <异常的处理语句>
[else:
<没有异常产生时的处理语句>]
在中括号[]内的语法,表示是可以省略的。

使用 try…except 语句的工作原理如下:

提示:异常的名称可以是空白的,表示此 except 语句处理所有类型的异常。异常的名称也可以是一个或多个。可以使用不同的 except 语句处理不同的异常。

例如,下面捕捉 ZeroDivisionError 异常,并显示“数值不能除以零”的字符串:
try:
    12/0
except ZeroDivisionError:
    print("数值不能除以零")
输出结果如下:
数值不能除以零

【示例1】在一个 except 语句内捕捉 IndexError 与 TypeError 两个异常。
s=[100,200,300,400]
def get (n):
    try:
        if n < 200:
            data = s[4]  #IndexError异常
        else:
            file = open(100,200,300,400)  #TypeError异常
    except (IndexError, TypeError):
            print ("发生异常")
  
get (100)
get (200)
保存并运行程序,输出结果如下:
发生异常
发生异常

下面将 IndexError 与 TypeError 两个异常分别使用不同的 except 语句进行处理。

【示例2】使用不同的except语句进行处理异常。
a = [100, 200, 300,400]
def getn(n):
    try:
        if n < 200:
            data = a[4]
        else:
            file = open(100,200,300,400)
    except IndexError:
           print ("a列表的索引值错误")
    except TypeError:
            print ("open()函数的参数类型错误")
  
getn(100)
getn(300)
输出结果如下:
a列表的索引值错误
open()函数的参数类型错误

异常全捕捉

在实际开发过程中,异常可能比较多,为了简便操作,可以一次性全捕捉所有预料的异常。下面使用一个 except 语句处理所有的异常。

【示例3】Python 全捕捉所有的异常。
a = [100, 200, 300,400]
def getn(n):
   try:
       if n < 200:
           data = s[4]
       else:
           file = open(100,200,300,400)
   except:
           print ("捕获所有的异常")
  
getn(100)
getn(300)
输出结果如下:
捕获所有的异常
捕获所有的异常

从运行结果可以看出,可以在 except 子句中忽略所有的异常类,从而让程序输出自定义的异常信息。

注意:这种全捕捉的方式在实际开发中需要特别注意,因为这样的捕捉方式会捕获所有预先想到的错误。

异常中的 else

else 语句内的语句是没有异常发生时的处理程序。下面使用 else 语句处理没有异常时的情况。

注意,使用 else 语句时,一定要有 except 语句才行。

【示例4】异常中的 else。
def get(n):
    try:
        if n == 100:
             data = s[4]
        elif 200 <= n <= 500:
             file = open(100,200,300)
    except:
            print ("有错误发生")
    else:
            print ("没有错误发生")
  
get(100)
get(300)
get(800)
输出结果如下:
有错误发生
有错误发生
没有错误发生

从运行结果可以看出,没有发生异常时,会执行 else 子句的流程。由此可见,当程序没有发送异常时,通过添加一个 else 子句,可以帮助我们更好地判断程序的执行情况。

异常中的pass

用户可以在 except 语句内使用 pass 语句来忽略所发生的异常。

下面的例子将列表 a 内的所有元素相加,并输出元素相加的总和。

【示例5】异常中的 pass。
a = ["100", "200", "苹果", "香蕉", "100"]
sm = 0
for n in a:
    try:
        sm += int(n)
    except:
        pass
  
print (sm)
输出结果如下:
400

从运行结果可以看出,sm 的值是可转换的3个元素(100、200 和 100)的和。

上述代码中的 int() 函数将字符串转换为整数。当 int() 函数无法将字符串转换为整数时,就会输出 ValueError 异常。在 except 语句内使用 pass 语句可以忽略所发生的 ValueError 异常。

Python 异常类的实例

每当有一个异常被输出时,该异常类就会创建一个实例,此实例继承了异常类的所有属性。

每一个异常类实例都有一个 args 属性。args 属性是一个元组格式,这个元组格式可能只包含错误信息的字符串(1-tuple),也可能包含两个以上的元素(2-tuple、3-tuple…)。异常类不同,这个元组格式也不同。

下面输出一个 IndexError 异常:
>>>x = [100, 200, 300]
>>>print (x[8])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
从运行结果可以看出,输出了一个 IndexError 异常,信息字符串是“list index out of range”。

下面使用 try…except 语句捕捉上面的 IndexError 异常。
try:
    x = [100, 200, 300]
    print (x[8])
except IndexError as inst:
    print (inst.args[0])
输出结果如下:
list index out of range

在 except 语句的右方加上一个 inst 变量,它是一个异常类实例。当 IndexError 异常发生时,inst 实例就会被创建。inst 实例的 args 属性值是一个元组,输出该元组的第一个字符串就是 IndexError 异常的错误信息字符串“list index out of range”。

下面的示例会输出 FileNotFoundError 异常,args 属性的 tuple 格式是:

错误号码,错误信息字符串,[文件名称]

文件名称有可能不出现。
try:
    file = open("mm", "r")
except FileNotFoundError as inst:
    print (inst.args)
输出结果如下:
(2, 'No such file or directory')

下面的示例会输出 SyntaxError 异常,args 属性的元组格式是:

错误信息字符串,(文件名称,行号,行内偏移值,文字)

请看下面的代码:
try:
    a = "100 >>>30"
    exec (a)
except SyntaxError as inst:
    print (inst.args)
输出结果如下:
('invalid syntax', ('<string>', 1, 7, '100 >>>30\n'))

使用下面的方式可以将 Python 解释器提供的错误信息字符串打印出来。
try:
    12 / 0
except ZeroDivisionError as errorMsg:
    print (errorMsg)
输出结果如下:
division by zero

从运行结果可以看出,errorMsg 的内容是“division by zero”,是由 Python 解释器设置的。

清除异常

Python 中的 try…finally 语句可以用于清除异常。无论 try 语句内是否运行失败,finally 语句一定会被运行。

注意,try 与 except 语句可以搭配使用,try 与 finally 语句也可以搭配使用,但是 except 与 finally 语句不能放在一起使用。

下面的示例是没有异常发生,fanally 语句内的程序代码还是被运行。
try:
    a = 100
finally:
    print ('异常已经清除啦')
输出结果如下:
异常已经清除啦

下面的示例是发生了 ValueError 异常,fanally 语句内的程序代码还是被运行。
try:
    raise ValueError
finally:
    print ('异常已经清除啦')
程序运行输出结果如下:
异常已经清除啦
  raise ValueError
ValueError

推荐阅读