1 语法错误
产生语法错误时,解析器会重复错误的行,并且使用一个箭头指向错误行中最早发现错误的位置。错误便是由箭头之前的符号引发的(至少是在此处检测到的)。文件名与行数将会被打印出来,当输入来自脚本时用以得知在哪里找寻错误。
2 异常
在执行期间检测到的错误称之为异常,它们通常不会无条件失败。
大多数异常并不是由程序处理并输出错误信息,这些异常称为内置异常,例如,除零引发的ZeroDivisionError。
异常有着不同的类型,异常类型将会作为异常信息的一部分输出。
作为异常类型打印的字符串实际上是被引发的内置异常的名称。
这一点对于所有的内置异常都适用,但是对于用户自定义的异常并不是一定可行(即使这是非常有用的惯例)。
标准异常名称是内置标识符,并不是保留关键字。
错误信息的剩余部分是每个错误类型以及造成的原因的详尽描述。
错误信息的前一部分以堆栈形式显示了异常发生的上下文。它通常包括列出堆栈回溯的源行数,但是,它不会显式从标准输入读取的行数。
3 处理异常
while True:
try:
x = int(raw_input("Enter a number: "))
break
except ValueError:
print "Try again..."
note:在输入整数类型的值之前,不断提示输入。
try语句处理过程:
- 首先,try子句(try与except关键字之间的语句)将会运行。
- 如果没有异常发生,except子句将会被跳过并且办成try语句的执行。
- 如果在执行try子句的过程中发生了异常,try子句的剩余部分将会被跳过。接着,如果异常类型匹配except关键字之后的异常名,except子句将被执行,然后执行try子句之后的语句。
- 如果一个异常发生,但是except之后的异常名称没有匹配发生的异常,该异常将会被传递给外层try语句,如果始终没有找到异常的处理程序,执行将会被终止,输出错误信息。
一个try语句可以有多个except子句,用来指定不同类型异常的处理程序。至多只有一个处理程序被运行。
处理程序只会处理发生在对应try语句中的异常,不会处理同一try语句的其他对应处理程序中发生的异常。
# except子句可以使用由多个异常组成的元组
try :
pass
except (RuntimeError, TypeError, NameError):
pass
import sys
try:
f = open('ttt')
s = f.readline()
i = int(s.strip())
print i
except IOError as e:
print e.args
print e.errno, e.strerror
except ValueError:
print 'convert failure'
except:
print 'Unexcepted error:', sys.exc_info()[0]
raise
else:
print "success"
note:except不带异常,会捕获所有的异常。
note:else子句将会在try子句不抛出异常的情况下执行。
note:except xxx as xx:用于为异常指定绑定的变量,异常实例的参数存储在异常的args属性中。
如果异常有参数,参数将会作为未处理的异常的最后一部分信息打印出来。
# 处理try调用的函数引发的异常
def this_falis():
x = 1/0
try:
this_falis()
except ZeroDivisionError as detail:
print detail
4 提出异常
# 手动提出异常
raise NameError("sdfs")
# except再抛出异常
try:
raise NameError('aaaa')
except NameError:
print "except"
raise
5 用户自定义异常
# 定义异常MyError,使用value属性替换args属性
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
当创建一个可能提出多个不同异常的模块时,常见的操作是在模块中创建建一个异常基类,然后针对不同的错误状况创建特定的异常子类。
大多数的异常一般以“Error”为结尾命名,类似标准异常的命名。
许多标准模块定义了自己的异常,用于输出在自己定义的函数中可能发生的错误。
6 定义清理行为
使用finally子句定义清理行为,无论在什么情况下,清理行为都必须执行。
# 定义清理行为
try:
raise KeyboardInterrupt
finally:
print '!!!!'
在离开try语句之前,无论异常是否发生,finally子句总会执行。当try子句中产生了异常并且此异常没有对应的except子句(或是异常产生于except或else子句中),在finally子句执行之后,此异常才会被再抛出。当try子句中的语句通过break、continue或return语句离开了try子句,此时finally子句会在离开程序的位置执行。
实际应用程序中,finally一般用于释放外部资源(例如文件或网络连接),这样无论资源的使用是否正常执行,都可以完成资源释放。
7 预定义清理行为
一些对象定义了不需要此对象时的标准清理行为,无论使用对象的操作是否执行成功。
with open("sss") as f:
for line in f:
print line