finally
语句中需要try...except...finally
。我认为,此代码块try:
run_code1()
except TypeError:
run_code2()
other_code()
与使用
finally
的代码块相同:try:
run_code1()
except TypeError:
run_code2()
finally:
other_code()
我想念什么吗?
#1 楼
如果您提早返回,则会有所不同: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.
其他情况可能导致差异:
如果在except块内引发了异常。
如果在
run_code1()
中引发了异常,但不是TypeError
。其他控制流程语句,例如
continue
和break
语句。#2 楼
您可以使用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
语句,但是这种结构可以几年后,我写了一篇有关滥用
finally
的博客文章,读者可能会发现这很有趣。#3 楼
它们不相等。不管其他什么情况发生,最终代码都会运行。这对于必须运行的清除代码很有用。评论
不管发生什么其他事情,最终代码都会运行...除非存在无限循环。或断电。或os._exit()。要么...
–马克·拜尔斯
2012年7月18日在23:49
@Mark实际上,sys.exit会引发一个正常的异常。但是,是的,任何导致进程立即终止的事物都意味着没有其他执行。
–锑
2012年7月18日在23:52
@锑:谢谢。更改为os._exit。
–马克·拜尔斯
2012年7月18日23:53
只是想知道,为什么不能将清除代码放到除非如果发现例外就进入代码的情况下,否则就不能放在其中?
–斯蒂芬·雅各布
19年2月20日在6:45
@Stephen一方面,即使您从try块返回,代码也最终会运行。在这种情况下,您将不会点击except子句。
–锑
19年2月20日在7:43
#4 楼
要添加到上面的其他答案中,无论执行什么操作都执行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
子句无论出现异常都会执行,希望对您有所帮助。评论
即使您没有使用“ finally”子句也无法解决问题,因为OP想要知道两者之间的区别,这还是可行的,一个很好的例子会引起与IOError不同的错误,以表明在将异常传播到调用者之前,将执行finally子句块。
– Reda Drissi
19年3月7日在15:13
我不知道还有其他事。有用的知道。
– mazunki
19年11月5日在9:31
#5 楼
代码块不是等效的。如果finally
引发了run_code1()
之外的异常,或者TypeError
引发了异常,则run_code2()
子句也将运行,而在这种情况下,第一版other_code()
不会运行。#6 楼
如文档中所述,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子句对于释放外部资源很有用(例如文件或网络连接),无论资源使用是否成功。
#7 楼
在您的第一个示例中,如果run_code1()
引发了不是TypeError
的异常,会发生什么? ... other_code()
将不会执行。与
finally:
版本进行比较:保证other_code()
都将被执行,而不会引发任何异常。#8 楼
finally
用于定义“清理操作”。无论是否发生异常(即使您不处理),在离开finally
语句之前,无论如何都将执行try
子句。 第二个@Byers的例子。
#9 楼
完美的例子如下:try:
#x = Hello + 20
x = 10 + 20
except:
print 'I am in except block'
x = 20 + 30
else:
print 'I am in else block'
x += 1
finally:
print 'Finally x = %s' %(x)
#10 楼
当您要在运行主要工作的代码之前运行“可选”代码并且可选代码可能由于各种原因而失败时,也可以使用final。在以下示例中,我们不知道确切地说,
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()
上面的代码与第一个代码具有相同的作用。代码块,但更简洁。
#11 楼
几年来专业地使用delphi教会了我维护最终使用的清理例程。 Delphi几乎强制使用finally来清理在try块之前创建的所有资源,以免引起内存泄漏。这也是Java,Python和Ruby的工作方式。resource = create_resource
try:
use resource
finally:
resource.cleanup
无论尝试和最终之间的操作如何,资源都会被清理。另外,如果执行从未达到
try
块,也不会清除它。 (即create_resource
本身会引发异常),这会使您的代码“异常安全”。关于为什么您实际上需要一个finally块的原因,并非所有语言都可以。在C ++中,您自动调用了析构函数,这些析构函数在异常展开堆栈时强制执行清除。与尝试...最终语言相比,我认为这是朝着更干净的代码的方向迈进的一步。
{
type object1;
smart_pointer<type> object1(new type());
} // destructors are automagically called here in LIFO order so no finally required.
#12 楼
try块只有一个强制性子句:try语句。except,else和finally子句是可选的,并且基于用户的偏好。
最后:
Python离开try语句,它将在任何情况下在finally块中运行代码,即使它正在结束程序。例如,如果Python在except或else块中运行代码时遇到错误,则在停止程序之前仍将执行finally块。
评论
错了例外声明是强制性的。 – Lucas Azevedo 2月1日,12:04这是错误的,因为我刚刚编译并运行了带有try-finally块且没有“ except”子句的Python 3.5程序。
–丝束
19年4月11日在20:40
我本人尝试过,但我不敢相信,except子句不是强制性的。
–captainblack
19年6月3日在1:19
#13 楼
运行以下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))
每次尝试以下输入:
随机整数
正确的代码是586(尝试此操作,您将得到答案)
随机字符串
**在学习Python的早期阶段。
#14 楼
我试图在要阅读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子句引发另一个异常,则将已保存的
异常设置为新异常的上下文。
..更多此处
评论
您应该将open(data_file,'rb')用作src:pd.read_excel(src,'SheetSum')。它将自动关闭文件
– fferrin
20年6月22日在19:12
另外,您应该将此作为单独的问题发布。这个空间只是给定问题的答案
– fferrin
20年6月22日在19:13
评论
尝试:#x = Hello + 20 x = 10 + 20除外:打印'我在其他块中'x = 20 + 30其他:打印'我在其他块中'x + = 1最后:打印'最后x =% s'%(x)
–阿比吉特·萨胡(Abhijit Sahu)
17-10-2在6:32