8.3 异常处理
编写可以处理可选择的异常是可能的。 看看下面的例子,要求用户输入一个合法的整数类型,但是允许用户打断程序()用control-c或者其他操作系统支持的语言;注意一个用户产生的终端会引发一个keyboardInterrupt 异常。
>>> while True:
... try:
... x = int(input("Please enter a number: "))
... break
... except ValueError:
... print("Oops! That was no valid number. Try again...")
...
Try语句如下工作:
l 首先,执行try句子里面内容。(在try和except关键字之间的语句)
l 如果没有异常发生,except语句就会跳过,try语句执行就结束。
l 如果在执行try语句过程中异常发生,剩下的语句就会跳过。 如果发生的 异常名称和except关键字之后的异常相同, except语句就会执行,它时在try语句之后执行的。
l 如果发生没有与except语句异常名称相匹配的异常,它就传递给try语句外部。如果发现没有处理的异常,就会抛出没有处理的异常并且打印出如上面的异常信息。
l
为了具体处理不同的异常,Try语句可以包含许多except语句。在但最多只有一个异常处理。 处理器只能处理发生发生在相应的try语句中的异常。而不是相同的try中发生的其他异常。
一个execpt可能作为一个括号括起来的元组里,命名多个异常,例如:
... except (RuntimeError, TypeError, NameError):
... Pass
最后一个except子句可以省略异常名称,以作为通配符使用。你需要谨慎使用这个。因为用这种方式很容易隐藏一个实际的程序错误。可以使用这种方法打印一条错误信息,然后重新抛出异常。(允许调用这处理这个异常)
import sys
try:
f = open(’myfile.txt’)
s = f.readline()
i = int(s.strip())
except IOError as err:
print("I/O error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
Raise
在try ... Except语句中也可以选择添加else语句,如果它存在,必须跟在所有except语句的后面,如果try语句不不想上抛一个异常但但又让接后的代码执行,那么这个语句就非常有用。例如:
for arg in sys.argv[1:]:
try:
f = open(arg, ’r’)
except IOError:
print(’cannot open’, arg)
else:
print(arg, ’has’, len(f.readlines()), ’lines’)
f.close()
使用else子句要比在try后面添加代码要好,因为它可以避免额外的捕捉异常。它们并不是由try... :keyword:except语句保护的代码所抛出。
当一个异常发生时,它可能有相关联的值,也可以成为异常的参数。参数的存在与类型依赖于异常的类型。
Except语句可以在异常名称后描述一个变量。这个变量与包含参数的异常实例相互绑定。为了方便起见,异常实例定义了_str_()方法以至于不需要调用参数.args可以直接打印参数。你也可以抛出异常前先实例化它,然后给它添加任何想要的属性。
>>> try:
... raise Exception(’spam’, ’eggs’)
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print(’x =’, x)
... print(’y =’, y)
...
<class ’Exception’>
(’spam’, ’eggs’)
(’spam’, ’eggs’)
x = spam
y = eggs
如果异常还有参数,对于没处理的异常将会打印在异常信息中的最后一部分中。
异常处理器不仅仅处理那些try子句中立刻发生的异常,也会处理那些try子句中调用的函数内部发生的异常:例如::
>>> def this_fails():
... x = 1/0
...
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print(’Handling run-time error:’, err)
...
处理运行时的错误: int division or modulo by zero