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)