第八章 异常
8.1 什么是异常(异常都是立马执行的)
python用异常对象(exception object)表示异常情况。遇到错误后,会引发异常。如果异常对象未被处理或捕捉,程序就会用回溯(traceback,一种错误信息)终止执行。每个异常都是一些类的实例
8.2 按自己方式出错
8.2.1 raise
>>> raise Exception
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
raise Exception
Exception
>>> raise Exception("hyperdrive overload")#添加错误信息
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
raise Exception("hyperdrive overload")#添加错误信息
Exception: hyperdrive overload
表8-1描述了一些最重要的内建异常类:
表8-1 一些内建异常类
Exception 所有异常的基类
AttributeError 特性引用或赋值失败时引发
IOError 试图打开不存在文件(包括其他情况)时引发
IndexError 在使用序列中不存在的索引时引发
KeyError 在使用映射中不存在的键时引发
NameError 在找不到名字(变量)时引发
SyntaxError 在代码为错误形式时引发
TypeError 在内建操作或者函数应用于错误类型的对象时引发
ValueError 在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时引发
ZeroDivisionError 在除法或者模除操作的第二个参数为0时引发
8.2.2 自定义异常类型
如何创建?
确保自定义类是从Exception类继承的(直接或者间接)
class SomeCustomException(Exception): pass
重点 使用. try....except
Enter the first number: 10
Enter the second number: 0
Traceback (most recent call last):
File "/home/marlowes/MyPython/My_Exception.py", line 6, in <module>
print x / y
ZeroDivisionError: integer division or modulo by zero
使用try.....except
try:
x = input("Enter the first number: ")
y = input("Enter the second number: ")
print x / y
except ZeroDivisionError:
print "The second number can't be zero!"
让错误发生时,执行别的语句注:如果没有捕捉异常,它就会被“传播”到调用的函数中。如果在那里依然没有捕获,这些异常就会“浮”到程序的最顶层,也就是说你可以捕捉到在其他人的函数中所引发的异常。有关这方面的更多信息,请参见8.10节。 8.10(看不懂,之后再来看
异常的抛出机制:
1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler).
2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。
3、如果在最外层(全局“main”)还是没有找到的话,程序会带着栈跟踪终止,同时打印出traceback以便让用户找到错误产生的原因。
>>> def faulty():
... raise Exception("Something is wrong")
...
>>> def ignore_exception():
... faulty()
...
>>> def handle_exception():
... try:
... faulty()
... except:
... print "Exception handled"
...
>>> ignore_exception()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in ignore_exception
File "<stdin>", line 2, in faulty
Exception: Something is wrong
>>> handle_exception()
Exception handled
可以看到,faulty中产生的异常通过faulty->ingore_exception传播,最终导致栈跟踪,handle_exception同理
如果捕捉到了异常,但是又想重新引发它(也就是说要传递异常,不进行处理),那么可以调用不带参数的raise(还能在捕捉到异常时显式地提供具体异常,在8.6节会对此进行解释)。 重新把异常继续向上传递。
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 #关闭屏蔽
注:如果除零行为发生而屏蔽机制被打开,那么calc方法会(隐式地)返回None。换句话说,如果打开了屏蔽机制,那么就不应该依赖返回值。
8.4 使用多个except
1.使用多个子句
2.使用元组包含多个异常类型
8.6 捕捉对象
在except子句中访问异常对象本身
下面的示例程序会打印异常(如果发生的话),但是程序会继续运行:
try:
x = input("Enter the first number: ")
y = input("Enter the second number: ")
print x / y
except (ZeroDivisionError, TypeError), e:#as e 在python3.0中
print e
8.7 全捕捉
直接使用 except: (不加入错误类型),捕捉所有异常
危险
可以使用 except Exception,e: 会更好,这样可以对e做一些检查
8.8 else
没出现错误时,执行else
8.9 finally
不管异常是否发生,都执行
通常用来清理
x = None
try:
x = 1 / 0
finally:
print "Cleaning up..."
del x
在程序traceback之前,清理就已经完成。
推荐阅读
-
安装Visual Studio后所有程序出异常它霸道的管着 启用/禁用Visual studio实时调试
-
微博账号登陆时提示帐号异常需要发送短信验证?
-
系统中快捷方式图标显示异常怎么办 桌面快捷方式图标变成白色解决办法
-
Oracle ORA-22908(NULL表值的参考)异常分析与解决方法
-
SQL Server自定义异常raiserror使用示例
-
ABP vNext 不使用工作单元为什么会抛出异常
-
详解JavaScript中的异常处理方法
-
Android 后台发送邮件示例 (收集应用异常信息+Demo代码)
-
java 集合并发操作出现的异常ConcurrentModificationException
-
docker swarm 集群故障与异常详解