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

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

和这个finally的用法一样:

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

我遗漏了什么吗?


当前回答

下面是一段代码来澄清两者的区别:

...

try: 
  a/b
  print('In try block')
  
except TypeError:
  print('In except block')
  
finally: 
  print('In finally block')

print('Outside')

A b = 0,1

输出:

In try block 
In finally block 
Outside

(没有错误,除了跳过块。)


A b = 1,0

输出:

In finally block

Traceback (most recent call last):
a/b
ZeroDivisionError: division by zero

(没有为ZeroDivisionError指定异常处理,只执行finally块。)


A, b = 0, '1'

输出:

In except block 
In finally block 
Outside

(异常被正确处理,程序没有中断。)


注意:如果你有一个except块来处理所有类型的错误,finally块将是多余的。

其他回答

完美的例子如下:

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)

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

专业地使用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()。或断电,但无限循环或其他东西也属于这一类。

为了让Abhijit Sahu对这个答案的评论更好看,并突出显示语法:

像这样,你可以观察到在以下情况下哪个代码块发生了什么:

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)