Python 3 – 异常处理

Python 3 – 异常处理

Python提供了两个非常重要的功能,用于处理Python程序中的任何意外错误并向其中添加调试能力 –

  • 异常处理 − 在本教程中将介绍此功能。以下是Python中可用的标准异常列表 – 标准异常

  • 断言 − 此功能将在 Python 3中的断言 教程中介绍。

标准异常

以下是Python中可用的标准异常列表 –

序号 异常名及其描述
1 Exception 所有异常的基类
2 StopIteration 迭代器中的 next() 方法指向没有对象时引发。
3 SystemExit 由 sys.exit() 函数引发。
4 StandardError 除 StopIteration 和 SystemExit 之外所有内置异常的基类。
5 ArithmeticError 所有数字运算错误的基类。
6 OverflowError 当计算超过了数字类型的最大限制时引发。
7 FloatingPointError 浮点数计算失败时引发。
8 ZeroDivisonError 当任何数字类型的除数或模数为零时引发。
9 AssertionError 当断言语句失败时引发。
10 AttributeError 当属性引用或赋值失败时引发。
11 EOFError 当没有来自 raw_input() 或 input() 函数的输入并且到达文件结尾时引发。
12 ImportError 当导入语句失败时引发。
13 KeyboardInterrupt 当用户中断程序执行,通常是通过按下 Ctrl+c 引发。
14 LookupError 所有查找错误的基类。
15 IndexError 在序列中找不到索引时引发。
16 KeyError 在字典中找不到指定的键时引发。
17 NameError 当在本地或全局命名空间中找不到标识符时引发。
18 UnboundLocalError 当尝试访问函数或方法中的局部变量但未给它赋值时引发。
19 EnvironmentError 所有超出 Python 环境范围的异常的基类。
20 IOError 当输入/输出操作失败时引发,例如打印语句或使用 open() 函数打开不存在的文件时。
21 OSError 与操作系统相关的错误时引发。
22 SyntaxError 在 Python 语法中有错误时引发。
23 IndentationError 缩进未正确指定时引发。
24 SystemError 解释器发现内部问题时引发,但遇到此错误时 Python 解释器不会退出。
25 SystemExit | 25 | SystemExit 当使用sys.exit()函数退出Python解释器时引发。如果代码中未处理,则导致解释器退出。
26 TypeError 当尝试对指定数据类型进行无效操作或函数时引发。
27 ValueError 当数据类型的内置函数具有有效类型的参数,但指定的参数具有无效值时引发。
28 RuntimeError 当生成的错误不属于任何分类时引发。
29 NotImplementedError 当需要在继承类中实际实现的抽象方法未被实现时引发。

Python中的断言

断言是一种健全性检查,当你测试程序时,可以打开或关闭它。

  • 最简单的方法是把断言和一个 如果 语句(或者更准确地说,是一个否则引发异常的语句)进行比较。一个表达式被测试,如果结果为false,则会引发一个异常。

  • 断言由assert语句执行,它是Python中最新的关键字,在1.5版中引进。

  • 程序员经常在函数的开始位置放置assertions以检查有效输入,并在函数调用后检查有效输出。

assert语句

当遇到一个assert语句时,Python会评估随附的表达式,希望结果是true。如果表达式为false,则Python会引发一个AssertionError异常。

assert的语法是 –

assert Expression[, Arguments]

如果断言失败,Python将使用ArgumentExpression作为AssertionError的参数。AssertionError异常可以像其他异常一样被捕捉和处理,使用try-except语句。如果没有得到处理,它们将终止程序并产生traceback。

示例

这是一个函数,将给定的温度从开尔文转换为华氏度。由于0K是最冷的,如果看到负温度,函数就会中止。

#!/usr/bin/python3

def KelvinToFahrenheit(Temperature):
   assert (Temperature >= 0),"Colder than absolute zero!"
   return ((Temperature-273)*1.8)+32

print(KelvinToFahrenheit(273))
print(int(KelvinToFahrenheit(505.78)))
print(KelvinToFahrenheit(-5))

当执行上述代码时,将产生以下结果 –

32.0
451
Traceback (most recent call last):
File "test.py", line 9, in <module>
print KelvinToFahrenheit(-5)
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0),"Colder than absolute zero!"
AssertionError: Colder than absolute zero!

什么是异常?

异常是程序执行期间的事件,这些事件会中断程序的正常流程。通常情况下,当Python脚本遇到无法处理的情况时,它会引发异常。异常是代表错误的Python对象。

当Python脚本引发异常时,它必须立即处理异常,否则就会终止并退出。

处理异常

如果有一些可疑的代码可能会引发异常,您可以通过将可疑的代码放置在 try: 块中来保护您的程序。在 try: 块后,包括一个 except: 语句,后面跟着一段代码,该代码尽可能地处理问题。

语法

这里是简单的try….except…else语法 –

try:
   You do your operations here
   ......................
except ExceptionI:
   If there is ExceptionI, then execute this block.
except ExceptionII:
   If there is ExceptionII, then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

以下是关于上述语法的一些重要点 –

  • 单个 try 语句块可以拥有多个 except 语句。当 try 块包含可能抛出不同类型的异常的语句时,这是非常有用的。

  • 您也可以提供一般的 exception 子句,该子句可以处理任何异常。

  • 在 except 子句之后,您可以包含一个 else 子句,如果 try 块中的代码没有引发异常,则会执行 else 块中的代码。

  • else 块是一些不需要 try 块保护的代码的好地方。

示例

这个示例打开一个文件,在文件中写入内容,因为完全没有问题所以结束地很好 –

#!/usr/bin/python3

try:
   fh=open("testfile", "w")
   fh.write("这是用于异常处理的测试文件!")
except IOError:
   print("错误:找不到文件或读取数据")
else:
   print("已成功在文件中写入内容。")
   fh.close()

这会产生以下结果 –

已成功在文件中写入内容。

示例

这个示例尝试打开一个您没有写入权限的文件,所以它引发了异常 –

#!/usr/bin/python3

try:
   fh=open("testfile", "r")
   fh.write("这是用于异常处理的测试文件!")
except IOError:
   print("错误:找不到文件或读取数据")
else:
   print("已成功在文件中写入内容。")

这会产生以下结果 –

错误:无法找到文件或读取数据

不带任何异常的 except

您也可以使用未定义任何异常的 except 语句,如下所示 –

try:
   这里执行操作
   ......................
except:
   如果有任何异常,则执行此块。
   ......................
else:
   如果没有异常,则执行此块。

这种 try-except 声明语句会捕获所有发生的异常。尽管如此,使用这种 try-except 声明语句并不被认为是一种很好的编程实践,因为它会捕获所有异常,但不会使程序员确定问题可能发生的根本原因。

带有多个异常的 except 子句

您还可以使用相同的 except 语句来处理多个异常,如下所示 –

try:
   这里执行操作
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   如果给定异常列表中有任何异常,则执行此块。
   ......................
else:
   如果没有异常,则执行此块。

try-finally 子句

您可以在 try 块旁边使用 finally 块。无论 try-block 是否引发异常,finally 块都是放置必须执行的任何代码的地方。 try-finally 语句的语法如下 –

try:
   在这里执行操作;
   ...................... 
   由于任何异常,可能会跳过此操作。
finally:
   总会执行这个。
   ......................

注意 – 您可以提供 except 子句或 finally 子句,但不能同时使用两者。您不能同时使用 else 子句和 finally 子句。

示例

#!/usr/bin/python3

try:
   fh = open("testfile", "w")
   fh.write("这是我的异常处理测试文件!")
finally:
   print("错误:找不到文件或无法读取数据")
   fh.close()

如果您没有打开文件的写入权限,则会产生以下结果−

错误:找不到文件或无法读取数据

同样的例子可以更干净地写成以下形式 −

#!/usr/bin/python3

try:
   fh = open("testfile", "w")
   try:
      fh.write("这是我的异常处理测试文件!")
   finally:
      print ("即将关闭文件")
      fh.close()
except IOError:
   print("错误:找不到文件或无法读取数据")

这将产生以下结果−

即将关闭文件

当在 try 块中抛出异常时,执行立即传递到 finally 块。在执行 finally 块中的所有语句后,再次引发异常,并在下一个更高级别的 try-except 语句中处理异常(如果存在)

异常的参数

异常可以有一个 参数 ,这是一个值,它提供有关问题的附加信息。参数的内容因异常而异。通过在 except 子句中提供变量来捕获异常的参数,如下所示 −

try:
   在这里执行您的操作
   ......................
except ExceptionType as Argument:
   您可以在此处打印 Argument 的值...

如果您编写了用于处理单个异常的代码,则可以在 except 语句中的异常名称后面跟随变量。如果您正在捕获多个异常,则可以在异常的元组后面跟随变量。

此变量通常接收异常的值,其中包含异常的原因。该变量可以接收单个值或以元组形式的多个值。该元组通常包含错误字符串,错误号和错误位置。

示例

以下是单个异常的示例 −

#!/usr/bin/python3

# 在此定义一个函数。
def temp_convert(var):
   try:
      return int(var)
   except ValueError as Argument:
      print("参数不包含数字\n", Argument)

# 在此处调用上述函数。
temp_convert("xyz")

这将产生以下结果−

参数不包含数字
invalid literal for int() with base 10: 'xyz'

抛出异常

您可以通过使用 raise 语句以多种方式引发异常。 raise 语句的通用语法如下 −

语法

raise [异常名 [, 参数 [, traceback]]]

这里, 异常名 是异常的类型(例如,NameError),而 参数 是异常参数的值。参数是可选的;如果不提供,则异常参数为 None。

最后一个参数 traceback 也是可选的(在实践中很少使用),如果存在,则是用于异常的 traceback 对象。

示例

异常可以是字符串,类或对象。 Python 核心引发的大多数异常都是类,带有作为类示例的参数。 定义新异常非常容易,可以按如下方式完成−

def functionName( level ):
   if level <1:
      raise Exception(level)
      # 如果我们抛出了异常,下面的代码将不会被执行
   return level

注意 − 为了捕获异常,”except”从句必须引用与所抛出的异常相同的异常,无论是作为类对象还是简单字符串。例如,为了捕获上面的异常,我们必须如下编写 except 从句 −

try:
   这里放置业务逻辑代码...
except Exception as e:
   使用 e.args 处理异常...
else:
   这里放置其他代码...

下面的示例说明如何抛出异常 −

#!/usr/bin/python3

def functionName( level ):
   if level <1:
      raise Exception(level)
      # 如果我们抛出了异常,下面的代码将不会被执行
   return level

try:
   l = functionName(-10)
   print ("level = ",l)
except Exception as e:
   print ("级别参数错误",e.args[0])

上述代码将显示如下结果

级别参数错误 -10

用户自定义异常

Python 还允许您通过从标准内置异常派生出类来创建自己的异常。

以下是一个与 RuntimeError 相关的示例。在这里,创建了一个从 RuntimeError 派生的类。当捕获到异常时,这非常有用,当您需要显示更具体的信息时。

在 try 块中,抛出了用户定义的异常,并在 except 块中捕获。变量 e 用于创建 Networkerror 类的一个实例。

class Networkerror(RuntimeError):
   def __init__(self, arg):
      self.args = arg

因此,一旦您定义了上面的类,您可以如下抛出异常 −

try:
   raise Networkerror("Bad hostname")
except Networkerror as e:
   print(e.args)

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程