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

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

和这个finally的用法一样:

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

我遗漏了什么吗?


当前回答

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

其他回答

try块只有一个强制子句:try语句。 except、else和finally子句是可选的,基于用户的首选项。

最后: 在Python离开try语句之前,它将在任何条件下运行finally块中的代码,即使它正在结束程序。例如,如果Python在except或else块中运行代码时遇到错误,finally块仍将在停止程序之前执行。

如果你早点回来,情况就不一样了:

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语句。

我试图运行一个代码,我想读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块,

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来做真正重要的事情。

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


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