python finally 出错咋办,
有时,程序会打开一些物理资源(如数据库连接、网络连接、磁盘文件等。)在try块中,并且这些物理资源必须被显式回收。
Python的垃圾收集机制不会回收任何物理资源,只会回收内存中对象占用的内存。
那么你在哪里回收这些物理资源呢?在try块中回收还是在except块中回收?假设程序回收try块中的资源,按照图1所示的异常捕捉流程,如果try块中的一条语句抛出异常,该语句之后的其他语句通常得不到执行的机会,这将导致该语句之后的资源回收语句没有被执行。如果在except块中回收资源,有可能except块不会被执行,导致无法及时回收这些物理资源。
为了确保try块中打开的物理资源可以被恢复,异常处理机制提供了finally块。无论try块中的代码是否异常,无论执行哪个except块,甚至是在try块或except块中执行return语句,finally块总会被执行。
Python完整的异常处理语法结构如下:
尝试:
#业务实施代码
异常子异常:
#异常处理模块1
.
exceptSubException2ase:
#异常处理模块2
.
else:
#正常处理块
最后:
#资源恢复块
.在异常处理语法结构中,只有try块是必须的,也就是说:如果没有try块,那么除了block和finally block之外就不能有后续;Except block和finally block是可选的,但是except block和finally block至少出现其中一个,或者两个都出现;可以有多个except块,但捕捉父类异常的except块应该在捕捉子类异常的except块之后;不能有try块,既不能有except块,也不能有finally块;多个except块必须位于try块之后,finally块必须位于所有except块之后。
看程序。
进口货
deftest():
fis=无
尝试:
fis=open(a.txt )
异常错误:
打印(e.strerror)
#return语句强制该方法返回
return#
os。_出口(1)#
最后:
#关闭磁盘文件并回收资源
iffisisnotNone:
尝试:
(=NationalBureauofStandards)国家标准局
p;#关闭资源
fis.close()
exceptOSErrorasioe:
print(ioe.strerror)
print("执行finally块里的资源回收!")
test()上面程序在 try 块后增加了 finally 块,用于回收在 try 块中打开的物理资源。注意在程序的 except 块中 ① 处有一条 return 语句,该语句强制方法返回。在通常情况下,一旦在方法里执行到 return 语句,程序将立即结束该方法:现在不会了,虽然 return 语句也强制方法结束,但一定会先执行 finally 块的代码。
运行上面程序,将看到如下运行结果:
Nosuchfileordirectory
上面的运行结果表明在方法返回之前执行了 finally 块的代码。将 ① 处的 return 语句注释掉,取消 ② 处代码的注释,即在异常处理的 except 块中使用 os._exit(1) 语句来退出 Python 解释器。运行上面代码,将看到如下运行结果:
Nosuchfileordirectory
上面的运行结果表明 finally 块没有被执行。如果在异常处理代码中使用 os.exit(1) 语句来退出 Python 解释器,则 finally 块将失去执行的机会。
除非在 try 块、except 块中调用了退出 Python 解释器的方法,否则不管在 try 块、except 块中执行怎样的代码,出现怎样的情况,异常处理的 finally 块总会被执行。调用 sys.exit() 方法退出程序不能阻止 finally 块的执行,这是因为 sys.exit() 方法本身就是通过引发 SystemExit 异常来退出程序的。
在通常情况下,不要在 finally 块中使用如 return 或 raise 等导致方法中止的语句(raise 语句将在后面介绍),一旦在 finally 块中使用了 return 或 raise 语句,将会导致 try 块、except 块中的 return、raise 语句失效。看如下程序:
deftest():
上面程序在 finally 块中定义了一条 return False 语句,这将导致 try 块中的 return true 失去作用。运行上面程序,将打印出 False 的结果。
如果 Python 程序在执行 try 块、except 块时遇到了 return 或 raise 语句,这两条语句都会导致该方法立即结束,那么系统执行这两条语句并不会结束该方法,而是去寻找该异常处理流程中的 finally 块,如果没有找到 finally 块,程序立即执行 return 或 raise 语句,方法中止;如果找到 finally 块,系统立即开始执行 finally 块,只有当 finally 块执行完成后,系统才会再次跳回来执行 try 块、except 块里的 return 或 raise 语句;如果在 finally 块里也使用了 return 或 raise 等导致方法中止的语句,finally 块己经中止了方法,系统将不会跳回去执行 try 块、except 块里的任何代码。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。