Python 中的异常处理

2023-09-17 22:15:22

异常的原因通常是程序本身之外的。例如,输入不正确、IO 设备故障等。由于程序在遇到异常时突然终止,因此可能会损坏系统资源,例如文件。 因此,应妥善处理异常,以防止程序突然终止。

Python 使用 tryexcept 关键字来处理异常。这两个关键字后跟缩进块。

语法:
try :
    #statements in try block
except :
    #executed when error in try block

try: 块包含一个或多个可能遇到异常的语句。 如果此块中的语句执行而没有异常,则跳过后续的 except: 块。

如果确实发生异常,程序流将传输到 except: 块。except:块中的语句旨在适当地处理异常的原因。 例如,返回相应的错误消息。

您可以在 except 关键字后指定异常类型。仅当发生指定的异常时,才会执行后续块。 单个 try 块中可能有多个具有不同异常类型的 except 子句。如果异常类型与任何 except 块都不匹配,它将保持未处理状态,程序将终止。

except 块之后的其余语句将继续执行,无论是否遇到异常。

下面的示例将在我们尝试用字符串划分整数时引发异常。

try:
    a=5
    b='0'
    print(a/b)
except:
    print('Some error occurred.')
print("Out of try except blocks.")

输出:

Some error occurred.
Out of try except blocks.

您可以在 except 关键字前面提及特定类型的异常。仅当发生指定的异常时,才会执行后续块。 单个 try 块中可能有多个具有不同异常类型的 except 子句。如果异常类型与任何 except 块都不匹配,它将保持未处理状态,程序将终止。

try:
  a=5
  b='0'
  print(a+b)
except TypeError:
  print('TypeError Occurred')
except:
  print('Some error occurred.')  
print ("Out of try except blocks")

输出:

TypeError Occurred
Out of try except blocks

默认的except:块必须位于捕获特定错误的所有except块之后;否则Python将引发错误。

try:
  a=5
  b='0'
  print(a+b)
except:
  print('Some error occurred.')  #except: before other blocks
except TypeError:
  print('TypeError Occurred')
print ("Out of try except blocks")

输出:

File "main.py", line 4
    print(a+b)
    ^
SyntaxError: default 'except:' must be last

如上所述,单个 try 块可能有多个除块之外的块。以下示例使用两个 except 块来处理两种不同的异常类型:

try:
    a=5
    b=0
    print (a/b)
except TypeError:
    print('Unsupported operation')
except ZeroDivisionError:
    print ('Division by zero not allowed')
except:
  print('Some error occurred.')
print ('Out of try except blocks')

输出:

Division by zero not allowed
Out of try except blocks

但是,如果变量 b 设置为"0",则会遇到 TypeError 并由相应的 except 块处理。

否则,最后(else and finally)

在 Python 中,关键字 elsefinally 也可以与 try 和 except 子句一起使用。 如果 try 块内发生异常,则执行 except 块,如果发现 try 块无异常,则处理 else 块。

语法:
try:
    #statements in try block
except:
    #executed when error in try block
else:
    #executed if try block is error-free
finally:
    #executed irrespective of exception occured or not

finally 块由应处理的语句组成,无论 try 块中是否发生异常。 因此,无错误的 try 块会跳过 except 子句并进入 finally 块,然后再继续执行其余代码。 但是,如果 try 块中存在异常,则将处理相应的 except 块,并在继续执行其余代码之前处理 finally 块中的语句。

下面的示例接受来自用户的两个数字并执行其除法。它演示了 else 的用途,最后是块。

try:
  x,y = 10, 2
  z=x/y
except ZeroDivisionError:
  print("except ZeroDivisionError block")
  print("Division by 0 not accepted")
except:
  print('Some error occurred.')
else:
  print("Division = ", z)
finally:
  print("Executing finally block")
  x=0
  y=0
print ("Out of try, except, else and finally blocks." )

第一次运行是正常情况。显示 else 和最终块的输出,因为 try 块没有错误。

输出:

Division =  5.0
Executing finally block
Out of try, except, else and finally blocks.

第二次运行是除以零的情况,因此,执行 except 块和最终块,但不执行 else 块。

try:
  x,y = 10, 0
  z=x/y
except ZeroDivisionError:
  print("Cannot devide by zero. Try again")
  print("Division by 0 not accepted")
except:
  print('Some error occurred.')
else:
  print("Division = ", z)
finally:
  print("Executing finally block")
  x=0
  y=0
print ("Out of try, except, else and finally blocks." )

输出:

Cannot devide by zero. Try again
Division by 0 not accepted
Executing finally block
Out of try, except, else and finally blocks.

在第三次运行情况下,将发生未捕获的异常。finally 块仍在执行,但程序终止,并且在 finally 块之后不执行程序。

try:
  x,y = 10, "xyz"
  z=x/y
except ZeroDivisionError:
  print("except ZeroDivisionError block")
  print("Division by 0 not accepted")
except:
  print('Error occurred.')
else:
  print("Division = ", z)
finally:
  print("Executing finally block")
  x=0
  y=0
print ("Out of try, except, else and finally blocks." )

输出:

Error occurred.
Executing finally block
Out of try, except, else and finally blocks.

通常,finally 子句是清理流程中操作的理想位置。例如,关闭文件而不考虑读/写操作中的错误。这将在下一章中讨论。

引发异常(Raise an Exception)

Python 还提供了要在异常处理上下文中使用的 raise 关键字。它会导致显式生成异常。隐式引发内置错误。但是,可以在执行期间强制使用内置或自定义异常。

以下代码接受来自用户的号码。如果数字超出允许的范围,try 块将引发 ValueError 异常。

try:
  x,y=100,2
  z=x/2
  if z > 10:
    raise ValueError(z)
except ValueError:
  print(z, "is out of allowed range")
else:
  print(z, "is within the allowed range")

输出:

50.0 is out of allowed range

在这里,引发的异常是ValueError类型。但是,您也可以引发自定义异常类型。 访问 Python 文档以了解有关 user defined exceptions 的更多信息。

本文内容总结: