9.3.4 捕捉对象
使用except子句捕捉了多个异常,但都是根据异常类来输出异常信息的。例如,如果抛出的是NegativeException类,就会输出"负数异常"信息。不过这么做是有问题的,因为可能有多处代码都抛出了同一个NegativeException类,尽管异常类似,但会有细微的差别。为了更进一步体现异常的差异性,需要为异常类执行一个变量,也可以称为异常对象。其实raise语句抛出的异常类最终也是被创建了异常对象后才抛出的。也就是说,except子句捕捉到的都是异常对象,这里只是给这些异常对象一个名字而已。
为异常对象指定名字需要用as关键字。
try:
...
except 异常类 as e:
...
except(异常类1,异常类2,异常类3,...,异常类n):
...
如果使用print函数输出e,会将通过构造方法参数传给异常对象的异常信息输出到Console。
[例 9.5] 本例会改进9.3的代码用同一个except子句捕捉多个异常,并为这些异常指定一个异常对象变量,当输出异常对象时,就会输出相应的异常信息。
class NegativeException(Exception):
pass
class ZeroException(Exception):
pass
class specialcalc:
def add(self,x,y):
if x < 0 or y < 0:
# 为异常指定异常信息
raise NegativeException('x和y都不能小于0')
return x + y
def sub(self, x, y):
if x - y < 0:
# 为异常指定异常信息
raise NegativeException('x与y的差值不能小于0')
return x - y
def mul(self, x, y):
if x == 0 or y == 0:
# 为异常指定异常信息
raise ZeroException('x和y都不能等于0')
return x * y
def div(self, x, y):
return x / y
while True:
try:
calc = specialcalc()
expr = input('请输入要计算的表达式,例如,add(1,2):')
if expr == 'exit':
break;
result = eval('calc.' + expr)
print('计算结果:{:.2f}'.format(result))
# 同时捕捉NegativeException和ZeroException异常,并为其指定一个异常对象变量e
except(NegativeException,ZeroException) as e:
# 输出相应的异常信息
print(e)
# 捕捉ZeroDivisionError异常
except ZeroDivisionError as e:
# 输出相应的异常信息
print(e)
except:
print('******其他异常******')
输出结果:
请输入要计算的表达式,例如,add(1,2):add(4,3)
计算结果:7.00
请输入要计算的表达式,例如,add(1,2):add(-4,1)
x和y都不能小于0
请输入要计算的表达式,例如,add(1,2):sub(3,6)
x与y的差值不能小于0
请输入要计算的表达式,例如,add(1,2):mul(0,4)
x和y都不能等于0
请输入要计算的表达式,例如,add(1,2):div(5,0)
division by zero
请输入要计算的表达式,例如,add(1,2):exit
运行上面的代码,通过输入相应的操作数,会抛出NegativeException、ZeroException和ZeroDivisionError异常。从输出的异常信息可以看出,e就是这些输出的异常信息。当add方法和sub方法都抛出NegativeException异常时,根据异常信息就可以更清楚的了解到底是什么引发的NegativeException异常。