在python中、如果异常并未被处理或捕捉_《Python基础教程》第8章 异常

本章将学习创建和引发自定义的异常,以及处理异常的各种方法。

8.1 什么是异常

程序运行中的错误或者不期望发生的事情就是异常,为了防止这样的事件你可以使用大量的条件语句,但是这样做的成本会非常高并且没效率。

在Python中,用异常对象(exception object)来表示异常。如果异常对象未被处理或者捕捉,程序就会使用回溯(Traceback,一种错误信息)来终止程序。事实上每个异常都是一些异常类的实例,异常类的实例在不同情况被引发,并且都能够被捕捉到后进行错误处理,而不至于程序运行失败。

8.2 按自己的方式出错

8.2.1 raise语句

有很多内建的异常类,详细介绍可以查询Python的文档“Built-in Exception”相关部分。

可以使用dir列出exceptions模块内容:

>>> import exceptions

>>> dir(exceptions)

['ArithmeticError', 'AssertionError', ...]

下面是使用内建异常类的简单例子:

>>> raise Exception

Traceback (most recent call last):

File "", line 1, in

Exception

>>> raise Exception('hyperdriver overload')

Traceback (most recent call last):

File "", line 1, in

Exception: hyperdriver overload

8.2.2 自定义异常类

如果内建异常类不能满足程序的需求,可以自定义异常类。只需要保证自定义异常类是直接或者间接从Exception类继承的即可:

class SomeCustomException(Expception): pass

8.3 捕捉异常

假如有一个要让用户输入两个数来整除的程序是这样的:

n = input('Enter your first number:')

m = input('Enter your second number:')

print n / m

$ python class.py

Enter your first number:10

Enter your second number:0

Traceback (most recent call last):

File "class.py", line 3, in

print n / m

ZeroDivisionError: integer division or modulo by zero

可以通过捕捉异常来处理它们:

try:

n = input('Enter your first number:')

m = input('Enter your second number:')

print n / m

except ZeroDivisionError:

print 'The second number can not be zero!'

$ python class.py

Enter your first number:10

Enter your second number:0

The second number can not be zero!

我们虽然捕捉了异常并打印了信息,实际上却可以不处理它,而让它继续传递。

如下是一个有 "屏蔽" ZeroDivisionError错误的代码示例。当muffled=Fasle时,会直接打印错误信息;否则异常会传递给上层调用者。

class MuffledCalculator:

muffled = False

def calc(self, expr):

try:

return eval(expr)

except ZeroDivisionError:

if self.muffled:

print 'Division by zero is illegal.'

else:

raise

>>> c = MuffledCalculator()

>>> c.calc("12/0")

Traceback (most recent call last):

File "class.py", line 12, in

c.calc("12/0")

File "class.py", line 5, in calc

return eval(expr)

File "", line 1, in

>>> c.muffled = true

>>> c.calc("12/0")

ZeroDivisionError: integer division or modulo by zero

8.4 不止一个except子句

在前面的例子中,还会有别情况,比如用户输入的如果是字符串,直接进行除法运算可能导致TypeError的异常,这时候就可以用多个except子句:

try:

n = input('Enter your first number:')

m = input('Enter your second number:')

print n / m

except ZeroDivisionError:

print 'The second number can not be zero!'

except TypeError:

print 'That was not number, is it?'

8.5 用一个块捕捉两个异常

上节中的多种异常情况如果不需要进行单独处理,能够更加简洁地用元组表示:

try:

n = input('Enter your first number:')

m = input('Enter your second number:')

print n / m

except (ZeroDivisionError, TypeError, NameError):

print 'Your number was bongus!'

当然只是打印错误信息并没有什么意义,另一个方案就是要求用户输入合理的数字直到可以进行运算位为止。

8.6 捕捉对象

如果不想终止程序运行,又想在except子句中获取错误信息,可以直接访问异常对象:

try:

n = input('Enter your first number:')

m = input('Enter your second number:')

print n / m

except (ZeroDivisionError, TypeError, NameError), e:

print e

$ python class.py

Enter your first number:10

Enter your second number:0

integer division or modulo by zero

8.7 真正的全捕捉

总有一些用户操作会躲过try/except的检查,比如在上面的例子中,用户什么也不输入直接回车:

$ python class.py

Enter your first number:

Traceback (most recent call last):

File "class.py", line 2, in

n = input('Enter your first number:')

File "", line 0

^

SyntaxError: unexpected EOF while parsing

要Python对所有异常全部进行捕捉可以在except的子句中什么异常类也不写:

try:

n = input('Enter your first number:')

m = input('Enter your second number:')

print n / m

except:

print 'Something wrong happen...'

8.8 万事大吉

在try/except子句中,如果发生了exception会走except分支,如果没有发生exception,还可以新增一个else分支。如下示例:

try:

print 'A Simple Task'

except:

print 'What? Something went wrong!'

else:

print 'Ah... I went as planed'

$ python class.py

A Simple Task

Ah... I went as planed

8.9 最后

除了else子句外,还有finally子句可以用来做一些清理工作(finally子句无论是否发生异常都会执行):

try:

1/o

except NameError:

print 'Unknown variable!'

else:

print 'That wents well'

finally:

print 'Clean up'

$ python class.py

Unknown variable!

Clean up

8.10 异常和函数

如果异常在函数中没有被处理,就会被传播至函数调用的地方,如此层层往上直到被处理。

8.11 异常之禅

在某些时候try/except和if/else子句可以实现同样的功能,但是if/else自然性和可读性差些,应该养成尽可能的多使用try/except的习惯。

“在做一件事情的过程中去处理可能出现的错误,而不是在做这件事情之前做大量的检查”。

8.12 小结

异常对象

警告[注:该章压根就没提到警告好么]

引发异常

自定义异常类

捕捉异常

else子句

异常和函数

8.12.1 本章的新函数

8.12.2 接下来学习什么

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值