python用异常对象来代表异常情况
如果异常对象未被处理或捕捉,程序就会用回溯(traceback,一种错误信息)来终止执行
而每个异常都是某些类的实例,可以引发,也可以捕捉
可以用一个类(Exception的子类)或者实例参数调用raise语句
若使用的是类,那么程序会自动创建类的一个实例
重要的内建异常类有——
raise Exception
raise Exception('Error! Error!')
#创建异常类——只需要让该类继承Exception即可
class SomCustomException(Exception):
pass
利用try/except语句
try:
......
except 异常类:
......
try:
x = input('被除数')
y = input('除数')
print x/y
except ZeroDivisionError:
print "The second number can'n be zero"
2/0
#捕捉到异常后,可以用不带参数的raise语句重新引发异常(传递异常)
class MuffledCalculator:
'设计一个具有屏蔽错误信息的计算器类'
muffled = False #屏蔽机制的开关,默认关闭
def calc(self, expr):
try:
return eval(expr) #通过eval函数执行expr求值字符串
except ZeroDivisionError:
if self.muffled:
print "Division by zero is illegal"
else:
raise #使用不带参数的raise语句,重新引发异常
calculator = MuffledCalculator()
calculator.calc('10/2')
calculator.calc('10/0') #关闭屏蔽机制的情况下
calculator.muffled = True #打开屏蔽机制
calculator.calc('10/0')
except子句可以有多个,用不同方式来处理多种异常
一个except子句的异常类可以有多个,用元组包含起来即可,用同一种方式来处理多种异常
#一个except子句含有多个异常类
try:
x = input('First number: ')
y = input('Second number: ')
print x/y
except (ZeroDivisionError, TypeError, NameError):
print 'Your numbers were bogus...'
python2中可以把对象作为except子句的第二个参数
python3中可以把except子句写成except ...... as ...
若只有一个异常,捕捉的对象作为单独的变量
若有多个异常,捕捉的对象会整合到一个元组里
try:
x = input('First number: ')
y = input('Second number: ')
print x/y
except (ZeroDivisionError, TypeError) as e: #(python3)
#except (ZeroDivisionError, TypeError), e: (python2)
print e #捕捉的对象可以用print打印出来
e
使用不带参数的except语句可以捕捉其余的所有异常
try:
x = input('First number: ')
y = input('Second number: ')
print x/y
except ZeroDivisionError:
print 'Error Division Zero'
except:
print 'Something wrong happened'
#事实上,不带参数的except只能捕捉Exception类的异常
我们还可以给它加上else子句
try:
print 'A simple task'
except:
print 'What? Something went wrong?'
else:
print 'Ah...It went as planned'
#这里可以和循环搭配
#不断捕捉异常,直到输入正确为止
#就把try语句写到循环While True内,在else子句写上break即可
finally子句:在try一系列代码块的最后执行
用于对可能的异常进行清理
x = None
try:
x = 1/0
finally:
print 'Cleaning up...'
del x
x
#出错后,x变量被删除了
#finally子句更多的是用于关闭文件 或者 网络套接字
假设有两个函数a和b,a函数的定义内又调用了b函数
当我们调用a函数时,在执行b函数的过程中出错
如果在b函数中没有处理异常,那么它会传播到a函数中
如果在a函数中没有处理异常,那么它会传播到主程序中
如果主程序也没有处理异常,那么程序会出错导致带着栈跟踪终止
try/except语句来处理可能遇到的错误更加自然和高效率
#效率比较——尝试访问一个不一定存在的键
person = {'name': 'Zk', 'age': 21,'Occupation':'Student'}
#if/else语句实现
def decribePerson(person):
print 'Decription of', person['name']
print 'Age:', person['age']
if 'Occupation' in person:
print 'Occuption:', person['Occupation']
decribePerson(person)
#此处如果Occpution存在,那么这个键会被访问两次(if中和print中)
#try/except语句实现
def decribePerson(person):
print 'Decription of', person['name']
print 'Age:', person['age']
try:
print 'Occuption:', person['Occupation']
except KeyError:
pass
decribePerson(person)
#此处如果Occupation存在,那么这个键只会被访问一次(print中)
#查看对象特性
class writer():
write = True
obj = writer()
try:
obj.write #尝试去访问这个特性
except AttributeError:
print 'The object is not writeable'
else:
print 'The object is writeable'