我不知道为什么我们最终需要尝试……最后陈述。在我看来,这个代码块

try:
    run_code1()
except TypeError:
    run_code2()
other_code()

和这个finally的用法一样:

try:
    run_code1()
except TypeError:
    run_code2()
finally:
    other_code()

我遗漏了什么吗?


当前回答

在第一个例子中,如果run_code1()引发了一个不是TypeError的异常,会发生什么?... Other_code()将不会被执行。

与finally: version: other_code()相比,无论引发任何异常,都保证执行。

其他回答

试着先运行这段代码,不要使用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来做真正重要的事情。

最后是“清理行动”的定义。finally子句在离开try语句之前的任何事件中执行,无论是否发生异常(即使您没有处理它)。

我赞同拜尔斯的例子。

专业地使用delphi几年教会了我如何使用最后来保护我的清理程序。Delphi在很大程度上强制使用finally来清理try块之前创建的任何资源,以免导致内存泄漏。这也是Java、Python和Ruby的工作原理。

resource = create_resource
try:
  use resource
finally:
  resource.cleanup

不管你在try和finally之间做了什么,资源都会被清理。此外,如果执行从未到达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.

它们不相等。最后,不管发生什么,代码都会运行*。 它对于清理必须运行的代码非常有用。


*: 正如Mark Byers所评论的,任何导致进程立即终止的事情也会阻止最终代码的运行。 后者可以是os._exit()。或断电,但无限循环或其他东西也属于这一类。

为了补充上面的其他答案,无论发生什么,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子句都会执行。希望这能有所帮助。