Exceptions
Python提供了两个非常重要的功能来处理Python程序中的任何意外错误并在其中添加调试功能 -
Exception Handling - 本教程将介绍这一点。 以下是Python中可用的列表标准异常: 标准异常 。
Assertions - 这将在Python中的Assertions教程中介绍。
标准例外清单 -
Sr.No. | 例外名称和描述 |
---|---|
1 | Exception 所有例外的基类 |
2 | StopIteration 当迭代器的next()方法没有指向任何对象时引发。 |
3 | SystemExit 由sys.exit()函数引发。 |
4 | StandardError 除StopIteration和SystemExit之外的所有内置异常的基类。 |
5 | ArithmeticError 用于数值计算的所有错误的基类。 |
6 | OverflowError 计算超出数字类型的最大限制时引发。 |
7 | FloatingPointError 浮点计算失败时引发。 |
8 | ZeroDivisionError 当为所有数字类型进行除法或模数为零时引发。 |
9 | AssertionError 在Assert语句失败的情况下引发。 |
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 在输入/输出操作失败时引发,例如在尝试打开不存在的文件时使用print语句或open()函数。 |
21 | IOError 引发与操作系统相关的错误。 |
22 | SyntaxError 在Python语法中出现错误时引发。 |
23 | IndentationError 没有正确指定缩进时引发。 |
24 | SystemError 解释器发现内部问题时引发,但遇到此错误时,Python解释器不会退出。 |
25 | SystemExit 使用sys.exit()函数退出Python解释器时引发。 如果未在代码中处理,则导致解释器退出。 |
26 | TypeError 尝试对指定数据类型无效的操作或函数时引发。 |
27 | ValueError 当数据类型的内置函数具有有效的参数类型但参数指定了无效值时引发。 |
28 | RuntimeError 当生成的错误不属于任何类别时引发。 |
29 | NotImplementedError 当实际上没有实现需要在继承类中实现的抽象方法时引发。 |
Python中的断言
断言是一种完整性检查,您可以在完成程序测试后打开或关闭。
想到断言的最简单方法是将它比作一个raise-if语句(或者更准确,即使是if-if-not语句)。 测试表达式,如果结果为false,则引发异常。
断言由assert语句执行,这是Python的最新关键字,在1.5版中引入。
程序员经常在函数的开头放置断言以检查有效输入,并在函数调用之后检查有效输出。
assert声明
遇到assert语句时,Python会对伴随的表达式求值,这有望成为现实。 如果表达式为false,则Python会引发AssertionError异常。
assert的syntax是 -
assert Expression[, Arguments]
如果断言失败,Python使用ArgumentExpression作为AssertionError的参数。 可以使用try-except语句像任何其他异常一样捕获和处理AssertionError异常,但如果不处理,它们将终止程序并产生回溯。
例子 (Example)
这是一个将温度从开尔文度转换为华氏度的函数。 由于开尔文的零度和它一样冷,如果看到负温度,该功能就会失效 -
#!/usr/bin/python
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脚本引发异常时,它必须立即处理异常,否则它将终止并退出。
处理异常
如果您有一些可能引发异常的suspicious代码,您可以通过将可疑代码放在try: block中来保护您的程序。 在try:block之后,包含一个except:语句,后跟一个代码块,尽可能优雅地处理问题。
语法 (Syntax)
这是try....except...else简单语法try....except...else blocks -
try:
You do your operations here;
......................
except <i>ExceptionI</i>:
If there is ExceptionI, then execute this block.
except <i>ExceptionII</i>:
If there is ExceptionII, then execute this block.
......................
else:
If there is no exception then execute this block.
以下是关于上述语法的几点重点 -
单个try语句可以有多个except语句。 当try块包含可能引发不同类型异常的语句时,这很有用。
您还可以提供一个通用的except子句,它处理任何异常。
在except子句之后,您可以包含else子句。 如果try:block中的代码不引发异常,则执行else-block中的代码。
else-block是一个不需要try:block保护的代码的好地方。
例子 (Example)
这个例子打开一个文件,在文件中写入内容并优雅地出来,因为根本没有问题 -
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
fh.close()
这会产生以下结果 -
Written content in the file successfully
例子 (Example)
此示例尝试打开您没有写入权限的文件,因此会引发异常 -
#!/usr/bin/python
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
这会产生以下结果 -
Error: can't find file or read data
except没有例外的条款
您也可以使用except语句,没有例外定义如下 -
try:
You do your operations here;
......................
except:
If there is any exception, then execute this block.
......................
else:
If there is no exception then execute this block.
这种try-except语句捕获所有发生的异常。 使用这种try-except语句虽然不被认为是一种很好的编程实践,因为它捕获了所有异常但却没有使程序员找出可能发生的问题的根本原因。
具有多个例外的except条款
您还可以使用相同的except语句来处理多个异常,如下所示 -
try:
You do your operations here;
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
If there is any exception from the given exception list,
then execute this block.
......................
else:
If there is no exception then execute this block.
try-finally Clause
您可以使用finally:块和try:块。 finally块是放置必须执行的任何代码的地方,无论try-block是否引发异常。 try-finally语句的语法是这样的 -
try:
You do your operations here;
......................
Due to any exception, this may be skipped.
finally:
This would always be executed.
......................
你也不能使用else子句和finally子句。
例子 (Example)
#!/usr/bin/python
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
finally:
print "Error: can\'t find file or read data"
如果您无权以书面模式打开文件,则会产生以下结果 -
Error: can't find file or read data
同样的例子可以写得更干净如下 -
#!/usr/bin/python
try:
fh = open("testfile", "w")
try:
fh.write("This is my test file for exception handling!!")
finally:
print "Going to close the file"
fh.close()
except IOError:
print "Error: can\'t find file or read data"
当在try块中抛出异常时,执行会立即传递给finally块。 在执行finally块中的所有语句之后,再次引发异常并在except语句中处理(如果存在于try-except语句的下一个更高层中)。
一个例外的争论
异常可以有一个argument ,该argument是一个值,提供有关该问题的其他信息。 参数的内容因异常而异。 您通过在except子句中提供变量来捕获异常的参数,如下所示 -
try:
You do your operations here;
......................
except <i>ExceptionType, Argument</i>:
You can print value of Argument here...
如果编写代码来处理单个异常,则可以在except语句中使用变量的名称。 如果要捕获多个异常,则可以使用变量跟随异常的元组。
此变量接收主要包含异常原因的异常值。 变量可以以元组的形式接收单个值或多个值。 此元组通常包含错误字符串,错误号和错误位置。
例子 (Example)
以下是单个例外的示例 -
#!/usr/bin/python
# Define a function here.
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print "The argument does not contain numbers\n", Argument
# Call above function here.
temp_convert("xyz");
这会产生以下结果 -
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
提出例外
您可以使用raise语句以多种方式引发异常。 raise语句的一般语法如下。
语法 (Syntax)
raise [Exception [, args [, traceback]]]
这里, Exception是Exception的类型(例如,NameError),而argument是exception参数的值。 参数是可选的; 如果未提供,则异常参数为None。
最后一个参数traceback也是可选的(在实践中很少使用),如果存在,则是用于异常的回溯对象。
例子 (Example)
异常可以是字符串,类或对象。 Python核心引发的大多数异常都是类,其中一个参数是类的一个实例。 定义新的异常非常简单,可以按如下方式完成 -
def functionName( level ):
if level < 1:
raise "Invalid level!", level
# The code below to this would not be executed
# if we raise the exception
Note:为了捕获异常,“except”子句必须引用抛出类对象或简单字符串的相同异常。 例如,要捕获上述异常,我们必须编写except子句,如下所示 -
try:
Business Logic here...
except "Invalid level!":
Exception handling here...
else:
Rest of the code here...
用户定义的例外
Python还允许您通过从标准内置异常派生类来创建自己的异常。
这是一个与RuntimeError相关的示例。 这里,创建了一个从RuntimeError子类RuntimeError类。 当捕获异常时需要显示更具体的信息时,这非常有用。
在try块中,引发用户定义的异常并在except块中捕获。 变量e用于创建Networkerror类的实例。
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
因此,一旦定义了上面的类,就可以按如下方式引发异常 -
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args