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

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

和这个finally的用法一样:

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

我遗漏了什么吗?


当前回答

我试图运行一个代码,我想读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]进程无法访问文件,因为它正在运行 由其他进程使用

我必须添加完整的尝试,除了与finally块,并告诉最后,我需要在任何情况下关闭文件,如:

def read_file(data_file):
    # data_file = '\rr\ex.xlsx'
    sheets = {}
    sheets_file = None
    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:
        if sheets_file:
            sheets_file.close()
    return sheets

read_file(file)
shutil.move( file, dirpath +'\\processed_files')

否则,文件仍然保持打开是后台。

如果出现finally,则指定一个清理处理程序。的尝试 子句,包括except和else子句。如果一个 异常发生在任何子句中而不被处理,则 异常被暂时保存。finally子句被执行。如果 有一个保存的异常,它在finally结束时被重新引发 条款。如果finally子句引发另一个异常,则保存 异常被设置为新异常的上下文。

..更多的在这里

其他回答

您可以使用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的博客文章,读者可能会觉得很有趣。

在这里你可以看到如何尝试,除了,否则,最终一起工作。实际上,由于您的代码没有'else',那么您所声称的是正确的。也就是说,你写的两个语句之间没有区别。但是如果在某个地方使用了'else',那么'finally'就有区别了

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

代码块是不等效的。如果run_code1()抛出TypeError以外的异常,或者run_code2()抛出异常,finally子句也将运行,而第一个版本中的other_code()在这些情况下不会运行。

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


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