第八篇 Python异常

在程序运行过程中,总会遇到各种各样的问题和错误。有些错误是我们编写代码时自己造成的,比如语法错误、调用错误,甚至逻辑错误。还有一些错误,则是不可预料的错误,但是完全有可能发生的,比如文件不存在、磁盘空间不足、网络堵塞、系统错误等等。这些导致程序在运行过程中出现异常中断和退出的错误,我们统称为异常。大多数的异常都不会被程序处理,而是以错误信息的形式展现出来。

异常有很多种类型,Python内置了几十种常见的异常,就在builtins模块内,无需特别导入,直接就可使用。需要注意的是,所有的异常都是异常类,首字母是大写的!

在发生异常的时候,Python会打印出异常信息,信息的前面部分显示了异常发生的上下文环境,并以调用栈的形式显示具体信息。异常类型作为信息的一部分也会被打印出来,例如ZeroDivisionError,NameError 和 TypeError。

1.1简单的捕获异常的语法

在程序开发中,如果对某些代码的执行不能确定是否正确,可以增加try来捕获异常:

1 try:
2     尝试执行的代码
3 except:
4     出现错误的处理

try…except…语句处理异常的工作机制如下:

  • 首先,执行try子句(在关键字try和关键字except之间的语句)
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。

1.2根据错误类型捕获异常

在程序执行时,可能会遇到不同类型的异常,可以针对不同的类型,做出不同的响应,此时就需要捕获错误类型。

1 try:
2     num = int(input("请输出整数:"))
3     result = (3 / num)
4     print(result)
5 except ZeroDivisionError:
6     print("除零错误")
7 except ValueError:
8     print("请输入正确的整数")

1.3捕获未知错误的异常

在开发时要预判所有可能出现的错误是有难度的,因此如果希望程序无论出现任何错误,都不会因为Python解释器抛出异常而终止,可以再增加一个except:Exception

1 try:
2     num = int(input("请输出整数:"))
3     result = (3 / num)
4     print(result)
5 except ZeroDivisionError:
6     print("除零错误")
7 except Exception as result:
8     print("未知错误 %s" %result)

说明:Exception可以捕获任意异常。

1.4异常捕获完整语法

 1 try:
 2     # 尝试执行的代码
 3     pass
 4 except 错误类型1:
 5     # 针对错误类型1,对应的代码处理
 6     pass
 7 except (错误类型2,错误类型3):
 8     # 针对错误类型2和错误类型3对应的代码处理
 9     pass
10 except Exception as result:
11     # 打印错误信息
12     print(result)
13 else:
14     # 没有异常才会执行的代码
15     pass
16 finally:
17     # 无论是否有异常,都会执行的代码
18 pass

说明:else是一个可选的子句,必须放在所有except后面,这个子句将在try子句没有发生任何异常时执行。另外还有一个finally子句,表示无论try和except的子句执行情况,finally子句都会执行。

1.5异常的传递

异常的传递:当函数/方法执行出现异常时,会将异常传递给函数/方法的调用一方。如果传递到主程序,仍然没有异常处理,则程序会终止。

 1 def demo01():
 2     return int(input("请输入一个整数:"))
 3 
 4 
 5 def demo02():
 6     return demo01()
 7 
 8 
 9 try:
10     print(demo02())
11 except ValueError:
12     print("请输入正确的整数")
13 except Exception as result:
14     print("未知错误 %s" % result)

1.6抛出raise异常

在实际的开发中,除了代码执行出错Python解释器会抛出异常外,还可以根据业务需求,主动抛出异常。

在开发时,如果业务需求希望抛出异常,可以创建一个Exception的对象,然后使用raise关键字抛出异常对象。

 1 def input_password():
 2 
 3     password = input("请输入密码:")
 4 
 5     if len(password) > 8:
 6         return password
 7 
 8     exp = Exception("密码长度小于8位")
 9 
10     raise exp
11 
12 
13 try:
14     user_password = input_password()
15     print(user_password)
16 except Exception as result:
17     print("存在错误 %s" % result)
18 
19 ------输出结果------
20 请输入密码:123456
21 存在错误 密码长度小于8位

1.7自定义异常

Python内置了很多的异常类,并且这些类都是从BaseException类派生的。

下面是一些常见异常类,请把它们记下来!这样你在见到大多数异常的时候都能快速准确的判断异常类型。

异常名解释
AttributeError 试图访问一个对象没有的属性
IOError 输入/输出异常
ImportError 无法引入模块或包;多是路径问题或名称错误
IndentationError 缩进错误
IndexError 下标索引错误
KeyError 试图访问不存在的键
KeyboardInterrupt Ctrl+C被按下,键盘终止输入
NameError 使用未定义的变量
SyntaxError 语法错误
TypeError 传入对象的类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
OSError 操作系统执行错误

大多数情况下,上面的内置异常已经够用了,但是有时候你还是需要自定义一些异常。自定义异常应该继承Exception类,直接继承或者间接继承都可以,例如:

class MyExcept(Exception):

    def __init__(self, msg):
        self.message = msg

    def __str__(self):
        return self.message

try:
    raise MyExcept('我的异常!')
except MyExcept as ex:
    print(ex)

异常的名字都以Error结尾,我们在为自定义异常命名的时候也需要遵守这一规范,就跟标准的异常命名一样。

posted @ 2019-02-11 23:05  博小园  阅读(240)  评论(0编辑  收藏  举报
回到顶部