Python finally-资源回收

有时,程序在那里 try 块中打开了一些物理资源(如数据库连接、网络连接和磁盘文件等。),必须显式回收。
Python 垃圾回收机制不会回收任何物理资源,只能回收内存中对象占用的内存。

那么这些物理资源在哪里回收呢? try 块里回收,还在 except 块中回收?假设程序在? try 资源在块中回收,根据图纸 1 如果所示的异常捕获过程, try 块中的一个句子引起异常,句子后面的其他句子通常没有机会执行,这将导致句子后面的资源回收句子无法执行。如果是 except 由于块中的资源回收,块中进行资源回收 except 块完全可能无法执行,这将导致这些物理资源无法及时回收。
为了保证一定的回收, try 物理资源在块中打开,异常处理机制提供 finally 块。不管 try 无论块中的代码是否异常,无论哪一个 except 块被执行,甚至在那里 try 块或 except 块中执行了 return 语句,finally 块总会被执行。
Python 异常处理的完整语法结构如下:
try: #实现业务代码 exceptSubExceptionase: #异常处理块1 ... exceptsubexceptionase: #异常处理块2 ... else: #正常处理块 finally: #资源回收块 ...
在语法结构的异常处理中,只有 try 块是必要的,也就是说,如果没有, try 块,则不能有后面的 except 块和 finally 块;except 块和 finally 块都是可选的,但是 except 块和 finally 至少其中一个块也可以同时出现;可以有多个 except 块,但捕获父类异常 except 捕获子异常的块应位于捕获子异常 except 块的后面;不能只有 try 块,既没有 except 块,也没有 finally 块;多个 except 块必须位于 try 块之后,finally 块必须位于所有位置 except 块之后。
看一下程序
importos
deftest():
fis=None
try:
fis=open("a.txt")
exceptOSErrorase:
print(e.strerror)
#return语句强制方法返回
return#①
os._exit(1)#②
finally:
#关闭磁盘文件,回收资源
iffisisnotNone:
try:
#关闭资源
fis.close()
exceptOSErrorasioe:
print(ioe.strerror)
print("在finally块中实施资源回收!")
test()上面程序在 try 块后增加了 finally 块,用于回收 try 块中打开的物理资源。注意程序 except 块中 ① 处有一条 return 句子,这个句子是强制返回的。一般情况下,一旦在方法中执行到 return 语句,程序会立即结束这种方法:现在不会了,虽然 return 语句也是强制性的结束方法,但必须先执行 finally 块的代码。
操作上述程序,将看到以下操作结果:
Nosuchfileordirectory 在finally中实施资源回收!
上述操作结果表明,该方法在返回方法之前已实施 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(): try: #因为finally块包含return语句 #因此,以下return语句失效 returnTrue finally: returnFalse a=test() print(a)
上面程序在 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 块中的任何代码。
