我不确定为什么我们在finally
语句中需要try...except...finally
。在我看来,这个代码块
try:
run_code1()
except TypeError:
run_code2()
other_code()
与使用finally
的
相同:
try:
run_code1()
except TypeError:
run_code2()
finally:
other_code()
我错过了什么吗?
答案 0 :(得分:319)
如果你早点回来会有所不同:
try:
run_code1()
except TypeError:
run_code2()
return None # The finally block is run before the method returns
finally:
other_code()
与此相比:
try:
run_code1()
except TypeError:
run_code2()
return None
other_code() # This doesn't get run if there's an exception.
可能导致差异的其他情况:
run_code1()
中引发了异常,但它不是TypeError
。continue
和break
语句。答案 1 :(得分:67)
您可以使用finally
确保文件或资源被关闭或释放,无论是否发生异常,即使您没有发现异常。(或者如果您不喜欢没有捕获特定的异常。)
myfile = open("test.txt", "w")
try:
myfile.write("the Answer is: ")
myfile.write(42) # raises TypeError, which will be propagated to caller
finally:
myfile.close() # will be executed before TypeError is propagated
在这个例子中,你最好使用with
语句,但这种结构可以用于其他类型的资源。
几年后,我写了a blog post关于滥用finally
读者可能觉得有趣的内容。
答案 2 :(得分:21)
它们并不等同。最后,无论发生什么,代码都会运行。它对于必须运行的清理代码很有用。
答案 3 :(得分:9)
要添加上面的其他答案,finally
子句无论何时执行,而else
子句仅在未引发异常时执行。
例如,写入没有例外的文件将输出以下内容:
file = open('test.txt', 'w')
try:
file.write("Testing.")
print("Writing to file.")
except IOError:
print("Could not write to file.")
else:
print("Write successful.")
finally:
file.close()
print("File closed.")
<强>输出:强>
Writing to file.
Write successful.
File closed.
如果存在异常,代码将输出以下内容(请注意,将文件保持为只读会导致故意错误。
file = open('test.txt', 'r')
try:
file.write("Testing.")
print("Writing to file.")
except IOError:
print("Could not write to file.")
else:
print("Write successful.")
finally:
file.close()
print("File closed.")
<强>输出:强>
Could not write to file.
File closed.
我们可以看到finally
子句不管异常都会执行。希望这会有所帮助。
答案 4 :(得分:7)
代码块不相同。如果finally
抛出run_code1()
以外的异常,或者TypeError
抛出异常,而第一个版本中的run_code2()
将无法运行,则也会运行other_code()
子句在这些情况下运行。
答案 5 :(得分:7)
在第一个示例中,如果run_code1()
引发的异常不是TypeError
,会发生什么? ...... other_code()
将不会被执行。
将其与finally:
版本进行比较:无论引发任何异常,都保证执行other_code()
。
答案 6 :(得分:3)
finally
用于定义“清理操作”。 finally
子句在离开try
语句之前的任何情况下都会执行,无论是否发生异常(即使您没有处理)。
我是第二个@ Byers的例子。
答案 7 :(得分:2)
最后也可以在你想要运行时使用&#34;可选&#34;在为主要工作运行代码之前的代码,并且可选代码可能由于各种原因而失败。
在下面的示例中,我们并不确切地知道store_some_debug_info
可能引发的异常类型。
我们可以跑:
try:
store_some_debug_info()
except Exception:
pass
do_something_really_important()
但是,大多数短信都会抱怨过于模糊的异常。此外,由于我们选择仅pass
出错,except
块并没有真正增加价值。
try:
store_some_debug_info()
finally:
do_something_really_important()
上面的代码与第一段代码具有相同的效果,但更简洁。
答案 8 :(得分:2)
完美的例子如下:
.mat-drawer{
background-color:red;
}
答案 9 :(得分:2)
正如documentation中所述,finally
子句旨在定义必须在所有情况下执行的清理操作。
如果存在
finally
,则指定'清理'处理程序。try
执行子句,包括任何except
和else
子句。如果 异常发生在任何条款中,并且不处理, 异常暂时保存。执行finally
子句。如果 有一个保存的例外,它会在finally
结束时重新提出 条款。
一个例子:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print("division by zero!")
... else:
... print("result is", result)
... finally:
... print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
如您所见,finally
子句在任何情况下都会执行。通过划分两个字符串引发的TypeError
不由except
子句处理,因此在finally
子句执行后重新引发。
在实际应用程序中,finally子句对于释放外部资源(例如文件或网络连接)非常有用,无论资源的使用是否成功。
答案 10 :(得分:2)
多年来专业地使用delphi教会我使用finally来保护我的清理程序。 Delphi几乎强制使用finally来清理try块之前创建的任何资源,以免导致内存泄漏。这也是Java,Python和Ruby的工作原理。
resource = create_resource
try:
use resource
finally:
resource.cleanup
无论你在try和finally之间做什么,都会清理资源。此外,如果执行永远不会到达try
块,则不会清除它。 (即create_resource
本身会抛出异常)它会使您的代码“异常安全”。
至于为什么你真的需要一个finally块,不是所有的语言都有。在C ++中,您自动调用析构函数,在异常展开堆栈时强制执行清理。我认为与try ... finally语言相比,这是更清洁代码方向的一步。
{
type object1;
smart_pointer<type> object1(new type());
} // destructors are automagically called here in LIFO order so no finally required.
答案 11 :(得分:2)
先尝试在没有 finally 块的情况下运行此代码,
1 / 0
导致除以零错误。
try:
1 / 0
print(1)
except Exception as e:
1 / 0
print(e)
然后尝试运行此代码,
try:
1 / 0
print(1)
except Exception as e:
1 / 0
print(e)
finally:
print('finally')
对于第一种情况,您没有 finally 块,
因此,当except块中发生错误时,程序将停止执行,并且您无法在except块之后执行任何操作。
但是对于第二种情况,
错误发生但在程序停止之前python首先执行finally块然后导致程序停止。
这就是为什么你使用 finally 并做真正重要的事情。
答案 12 :(得分:1)
我试图在我想阅读Excel工作表的地方运行代码。问题是,如果有一个没有工作表的文件说:SheetSum我无法将其移动到错误位置!我写的代码是:
def read_file(data_file):
# data_file = '\rr\ex.xlsx'
sheets = {}
try:
print("Reading file: "+data_file)
sheets['df_1'] = pd.read_excel(open(data_file,'rb'), 'SheetSum')
except Exception as excpt:
print("Exception occurred", exc_info=True)
return sheets
read_file(file)
shutil.move( file, dirpath +'\\processed_files')
给出错误:
[WinError 32]该进程无法访问文件,因为它正在 被另一个进程使用
我必须添加完整的try except with finally
块并告诉finally
,无论如何我都需要关闭文件:
def read_file(data_file):
# data_file = '\rr\ex.xlsx'
sheets = {}
try:
print("Reading file: "+data_file)
sheets_file = open(data_file,'rb')
sheets['df_1'] = pd.read_excel(sheets_file, 'SheetSum')
except Exception as excpt:
print("Exception occurred", exc_info=True)
finally:
sheets_file.close()
return sheets
read_file(file)
shutil.move( file, dirpath +'\\processed_files')
否则,文件仍然保持打开状态。
如果存在
finally
,则它指定清理处理程序。try
子句被执行,包括任何except
和else
子句。如果 异常发生在任何子句中且未处理, 例外已临时保存。finally
子句被执行。如果 有一个已保存的异常,它会在finally
的末尾重新引发 条款。如果finally
子句引发另一个异常,则保存的 异常设置为新异常的上下文。
..更多Here
答案 13 :(得分:0)
这里有一段代码来澄清区别:
...
try:
a/b
print('In try block')
except TypeError:
print('In except block')
finally:
print('In finally block')
print('Outside')
如果a, b = 2, 1
,输出:
In try block
In finally block
Outside
(没有错误,除了跳过块。)
如果a, b = 2, 0
,输出:
In finally block
ZeroDivisionError: division by zero
(没有为 ZeroDivisionError 指定异常处理并且只执行 finally 块。)
如果a, b = 2, '1'
,输出:
In except block
In finally block
Outside
(异常处理妥当,程序不中断。)
答案 14 :(得分:-1)
try块只有一个强制性子句:try语句。 else,else和finally子句是可选的,并且基于用户首选项。
最后: 在Python离开try语句之前,它将在任何情况下在finally块中运行代码,即使它正在结束程序。例如,如果Python在except或else块中运行代码时遇到错误,则在停止程序之前,finally块仍将执行。
答案 15 :(得分:-1)
运行以下Python3代码以了解最终需求:
案例1:
count = 0
while True:
count += 1
if count > 3:
break
else:
try:
x = int(input("Enter your lock number here: "))
if x == 586:
print("Your lock has unlocked :)")
break
else:
print("Try again!!")
continue
except:
print("Invalid entry!!")
finally:
print("Your Attempts: {}".format(count))
案例2:
count = 0
while True:
count += 1
if count > 3:
break
else:
try:
x = int(input("Enter your lock number here: "))
if x == 586:
print("Your lock has unlocked :)")
break
else:
print("Try again!!")
continue
except:
print("Invalid entry!!")
print("Your Attempts: {}".format(count))
每次尝试以下输入:
**在学习Python的早期阶段。