异常:
当Python检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"
如:打开一个不存在的文件
open("hm.txt", "r") # 打开文件 # FileNotFoundError: [Errno 2] No such file or directory: 'hm.txt' # FileNotFoundError -> 异常类型 # [Errno 2] No such file or directory: 'hm.txt' -> 异常信息描述
捕获异常
<1>捕获异常 try...except...
- 把可能出现问题的代码,放在try中
- 把处理异常的代码,放在except中
""" try: 执行可能发生异常的代码 except 异常类型: 如果发生异常执行的代码 """ try: open("hm.txt", "r") print("测试") # 发生异常后,这行代码就不走了 except FileNotFoundError: print("发生异常了") # open("hm.txt", "w") # 新增文件后,下次就不会报异常了 print("往下运行")
<2> except捕获多个异常
当捕获多个异常时,可以把要捕获的异常的名字,放到except 后,并使用元组的方式仅进行存储
""" try: 执行可能发生异常的代码01(不同的异常类型) 执行可能发生异常的代码02(不同的异常类型) except (异常类型1, 异常类型2,...): 如果发生异常执行的代码 """ try: open("hm.txt", "r") print(num) except (FileNotFoundError, NameError): print("捕获到异常了")
<3>获取异常的信息描述
""" try: 执行可能发生异常的代码 excpet 异常类型 as 临时变量名: 可以获得临时变量名 """ try: open("hm1.txt", "r") except FileNotFoundError as e: # as 临时变量 使用临时变量保存异常的信息描述 print("捕获到异常了", e) # 捕获到异常了 [Errno 2] No such file or directory: 'hm1.txt'
""" try: 执行可能发生异常的代码 excpet (异常类型1, 异常类型2, ....) as 临时变量名: 可以获得临时变量名 """ try: open("hm1.txt", "r") print(num) except (FileNotFoundError, NameError) as e: print(e) # [Errno 2] No such file or directory: 'hm1.txt' 打开文件不报异常时,显示的就是下一个异常信息
<4>捕获所有异常
""" try: 执行可能发生异常的代码 except Exception as 临时变量: 发生异常执行的代码 """ try: open("hm1.txt", "r") except Exception as e: # Exception 所有异常父类 print("捕获到了异常", e)
<5> else
try: open("hm.txt", "r") except: # 去掉Exception的简写 # try中的代码发生了异常执行except代码 print("except") else: # 如果try中的代码没有发生异常 就会执行else中的代码 print("else")
<6> try...finally...
在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。 比如文件关闭,释放锁,把数据库连接返还给连接池等
try: open("hm1.txt", "r") except: # try中的代码发生了异常执行except代码 print("except") else: # 如果try中的代码没有发生异常 就会执行else中的代码 print("else") finally: # 无论try中的异常代码是否发生异常 finally都会执行 print("finally")
try: open("hm1.txt", "r") except: # try中的代码发生了异常执行except代码 print("except") finally: # 无论try中的异常代码是否发生异常 finally都会执行 print("finally")
# 根本就没有捕获异常 还是会发生异常的(程序崩溃) try: open("hm1.txt", "r") finally: # 无论try中的异常代码是否发生异常 finally都会执行 print("finally")
异常的传递
1. try嵌套中
# try嵌套 try: try: open("hm1.txt", "r") finally: print("里面的finally") except: print("捕获到了异常")
如果try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递。。。
2. 函数嵌套调用中
def my_func1(): print(num) def my_func2(): my_func1() def my_func3(): my_func2() try: my_func3() except: print("异常")
def my_func1(): print(num) def my_func2(): my_func1() def my_func3(): try: my_func2() except: print("异常") my_func3() # 异常
def my_func1(): print(num) def my_func2(): try: my_func1() except: print("异常") def my_func3(): my_func2() my_func3() # 异常
def my_func1(): # 请写这种方式 try: print(num) except: print("异常") def my_func2(): my_func1() def my_func3(): my_func2() my_func3() # 异常
捕获异常是可以传递的
如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,那么这个异常会传递到函数B中,如果函数B有异常处理那么就会按照函数B的处理方式进行执行;如果函数B也没有异常处理,那么这个异常会继续传递,以此类推。。。如果所有的函数都没有处理,那么此时就会进行异常的默认处理,即通常见到的那样
def test1(): print("----test1-1----") print(num) print("----test1-2----") def test2(): print("----test2-1----") test1() print("----test2-2----") def test3(): try: print("----test3-1----") test1() print("----test3-2----") except Exception as result: print("捕获到了异常,信息是:%s" % result) print("----test3-2----") test3() print("------华丽的分割线-----") test2()
输出结果:
----test3-1----
----test1-1----
捕获到了异常,信息是:name 'num' is not defined
----test3-2----
------华丽的分割线-----
----test2-1----
----test1-1----
Traceback (most recent call last):
File "G:/yaya/pycharm/test1/Day1.py", line 19, in <module>
test2()
File "G:/yaya/pycharm/test1/Day1.py", line 7, in test2
test1()
File "G:/yaya/pycharm/test1/Day1.py", line 3, in test1
print(num)
NameError: name 'num' is not defined
当调用test3函数时,在test1函数内部产生了异常,此异常被传递到test3函数中完成了异常处理,而当异常处理完后,并没有返回到函数test1中进行执行,而是在函数test3中继续执行