异常处理

  • 异常就是程序运行过程中引发的错误,处理异常可以使程序更健壮。
  • 捕获异常使用tryexcepttry表示尝试执行可能出现异常的代码,except表示捕获出现的异常。
  • 语法
try:
    <可能出现异常的代码块>
# except (异常类型1, 异常类型2) as 别名:
excpet 异常类型1 as 别名:
    <对异常的处理代码块>
excpet 异常类型2 as 别名:    
    <对异常的处理代码块>
    ……
excpet:
    <对异常的处理代码块>
else:
    <没有出现异常时才执行的代码块>
finally:
    <不管抛不抛异常,都得执行的代码块>
  • 注意:异常类型大多数最终继承Exception类,那么以后捕获异常,这个类型可以指定成Exception
  • except还可以捕获多个类型的异常,但是当一个异常被捕获了,try语句后面的代码不会执行,不能同时捕获两个及以上的异常。
  • tryexceptelsefinally可以以下几种方式组合使用:
  • try-except
  • try-except-else
  • try-ecxept-else-finally
  • try-finally:这里要注意程序会崩溃的, 是没有捕获异常的。

异常处理机制:

  • Python遇到try语句,先尝试执行try包含的代码块,如果没有错误发生,执行try-except后面的语句
  • 如果发生错误,Python寻找一个符合该错误的异常语句,然后执行相应的execpt的处理代码。

异常传递(异常抛出机制)

  • 解释:当Python解释器执行代码时出现错误,在当前代码里面没有对异常进行捕获,那么异常会往外一层一层进行传递,直到最外层都没有捕获这个异常,那么程序就会崩溃;如果外层有异常捕获,那么程序就不会崩溃。
  1. 如果在运行时发生异常的话,解释器会找到相应的处理语句(称为handler)。
  2. 要是再当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。
  3. 如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因
    注意:虽然大多数数据会导致异常,但一个异常不一定代表错误,有时候他们只是一个警告,有时候他们可能是一个终止信号,比如退出循环等。
"""
内层的try-finally并没有对异常进行捕获处理,
异常就会传递给外层的try-except进行处理。
"""
try:
    try:
        my_list1 = []
        my_list1[1]
    finally:
        print("有没有异常哥都要执行")
except Exception as e:
    print(e)
    
"""
show1抛出异常,没有代码处理,将异常传递个show2,
show2也没有代码处理,将其再传给外层,
最后异常被try捕获,except处理
""" 
def show1():
    my_list2 = []
    print(my_list2[1])
def show2():
    show1()
try:
    show2()
except Exception as e:
    print(e)

常见异常

异常

描述

AssertionError

assert(断言)语句失败

AttributeError

试图访问一个对象没有的属性,比如foo.x,但是foo没有x这个属性。

IOError

输入、输出异常,基本上是文件无法打开。

ImportError

无法引入模块或者包,基本上是路径问题。

IndentationError

语法错误,代码没有正确对齐。

IndexError

下标索引超出列表边界,比如当x只有三个元素,却试图访问x[5]

KeyError

试图访问字典里不存在的键。

KerboardInterrupt

Ctrl + C被按下。

NameError

使用一个还未被赋值的变量。

SyntaxErrorPython

代码非法,代码不能解释。

TypeError

传入对象类型与要求的不符。

UnboundLocalError

试图访问一个还未被设置的局部变量,基本上是由于另一个同名全局变量导致的你以为正在访问它。

ValueError

传入一个调用者不期望的值,即使值得类型时正确的。

抛出自定义异常

  • 到目前为止,我们只讨论了如何捕捉异常,那么如何抛出异常呢?
  • 抛出异常使用raise关键字。
  • 扩展raise不光能够抛出自定义异常,系统异常也可以抛出。
    以后想要捕获所有的异常类型可以使用BaseExceptionException继承的就是BaseException,像Ctrl + C(强制中断)Exception捕获不了,BaseException就可以。
# 抛出自定义异常
class CustomException(Exception)
    def __init__(self, current_len, min_len):
        # 当前密码长度
        self.current_len = current_len
        # 要求最小的密码长度
        self.min_len = min_len

password = input("请输入您的密码:")
try:
    # 判断密码的长度
    if len(password) < 6:
        print("抛出异常")
        # raise抛出自定义异常
        raise CustomException(len(password), 6)
except BaseException as e:
    print("CustomException: 当前密码长度是:%d 要求密码最小长度是:%d" % 
         (e.current_len, e.min_len))

# 抛出系统异常
if 'a' > 5:
    # 指定抛出系统异常的话,异常必须是Python中存在的,不能瞎起,可以不对应
    raise TypeError("异常提示信息")  
--------------------------------------------------------------------------
Traceback(most recent call last):
File "<stdin>", line 2, in <module> TypeError:异常提示信息
--------------------------------------------------------------------------

assert 语句(True/False):忘了这是什么东西了???