python基础之异常
2016-01-27 20:06
711 查看
python用异常对象(exception object)来表示异常情况。遇到错误后,会引发异常。如果异常对象并未被处理或者捕获,程序就会用所谓的回溯(traceback,一种错误信息)终止执行。
按照自己的方式出错
在学习处理异常之前,我们先看下如何引发异常以及创建自己的异常类型:
(1)raise语句
为了引发异常。可以使用一个类(Exception的子类)或者实力参数调用raise语句:
>>> raise Exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception
>>> raise Exception('hello word')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: hello world
第一个例子raise Exception引发了一个没有任何错误信息的异常。后一个例子添加了错误信息hello world.
内建的异常类有很多,这里我们看下一些最重要的异常类:
类名 描述
Exception 所有异常的基类
AttributeError 特性引用或者赋值失败时引发
IOError 试图打开不存在文件时候引发
IndexError 在使用序列中不存在的索引时引发
KeyError 在使用映射中不存在的键时引发
NameError 在找不到名字(变量)时引发
SyntaxError 在代码为错误的形式时引发
TypeError 在内建操作或者函数应用错误类型对象时引发
ValueError 在内建操作或者函数应用正确类型的对象,但是该对象使用不适合的 值时引发
ZeroDivisionError 在除法或者模操作的第二个参数为0时引发
(2)自定义异常类
尽管内建的异常类已经包含了大部分的情况,但是有时候还是需要创建自己的类,那么如何创建自己的类呢,就像其它类一样,只是要确保是从Exception类继承:
class SomeCustomException(Exception): pass
如果你愿意,你也可以向你的异常类中添加方法。
捕捉异常
前面提到过,关于异常最有意思的地方就是可以处理它们(通常叫做诱捕或者捕捉异常)。这个功能可以使用try/except语句来实现。假设创建了一个让用户输入两个数,然后进行相加的程序:
x= input('Enter the first number:')
y= input('Enter the second number:')
print x/y
加入用户输入0作为第二个数:
Enter the first number:10
Enter the second number:0
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print x/y
ZeroDivisionError: integer division or modulo by zero
为了捕捉异常并且做出一些错误处理(本例中只是输出一些友好信息),可以这样:
try:
x= input('Enter the first number:')
y= input('Enter the second number:')
print x/y
except ZeroDivisionError:
print 'hello word'
Enter the first number:1
Enter the second number:0
hello word
如果捕捉到了异常,但是又想重新引发它,那么可以使用不带参数的raise。
举个例子,看看这么做的用处:考虑下一个能“屏蔽”ZeroDivisionError的计算器类。如果这个行为被激活,那么计算机就会打印错误信息,而不是让异常传播。如果在与程序内部使用引发异常又会更好,所以”屏蔽“机制就可以关掉了,下面是这样一个类的代码:
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
运行一下:
print calculator.calc('10/0')
Traceback (most recent call last):
File "./test.py", line 14, in <module>
print calculator.calc('10/0')
File "./test.py", line 7, in calc
return eval(expr)
File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
calculator.muffled=True
print calculator.calc('10/0')
Division by zero is illegal
None
不知一个except子句
如果在上面的那个程序里第二个数字输入非字符类型的值,那么
4000
就会产生第二个异常:
Enter the first number:1
Enter the second number:'a'
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print x/y
TypeError: unsupported operand type(s) for /: 'int' and 'str'
因为except子句值寻找ZeroDivisionError异常,这次的错误就溜过了检查并导致程序终止,为了捕捉这个异常,我们可以在try/except语句后面加上里一个except子句:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except ZeroDivisionError:
print 'a'
except TypeError:
print 'b'
用一个块捕捉两个异常
如果需要用一个块捕捉多个类型异常,那么可以将它们作为元组列出,像下面这样:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except (ZeroDivisionError,TypeError):
print 'hello world'
[root@localhost python]# ./test.py
Enter the first number:1
Enter the second number:'a'
hello world
捕捉对象
如果希望在excep子句中访问异常对象本身,可以使用两个参数(注意,就算捕捉到多个异常,也只需向except子句提供一个参数——一个元组),比如想让程序继续运行,但是又因为某种原因想记录下错误(比如只是打印给用户看),这个功能就很有用:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except (ZeroDivisionError,TypeError),a:
print a
[root@localhost python]# ./test.py
Enter the first number:1
Enter the second number:'a'
unsupported operand type(s) for /: 'int' and 'str'
真正的全捕获
就算程序可以处理好几种类型的异常,但是有些异常还是会从眼皮地下溜走,但是如果想用一段代码捕获所有的异常,就可以在except子句中忽略所有的异常类:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except:
print 'hello world'
警告:这样的全捕获是危险的,因为它会隐藏程序员未想到并且未做好准备处理的错误。这时还是使用except Exception,e这样好点
万事大吉
可以像条件和循环语句那样,给try/except语句加个else子句:
while True:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except Exception,e:
print e
else:
break
[root@localhost python]# ./test.py
Enter the first number:1
Enter the second number:0
integer division or modulo by zero
Enter the first number:''^[[Da
invalid syntax (<string>, line 1)
Enter the first number:'a'
Enter the second number:'a'
unsupported operand type(s) for /: 'str' and 'str'
Enter the first number:10
Enter the second number:2
5
最后.......
最后是finally子句,它可以用来在可能的异常后进行清理,它和try子句联合使用:
x=None
try:
x=1/0
finally:
print 'clean up'
del x
[root@localhost python]# ./test.py
clean up
Traceback (most recent call last):
File "./test.py", line 5, in <module>
x=1/0
ZeroDivisionError: integer division or modulo by zero
finally子句肯定会被执行,不管try子句中是否发生异常的。
按照自己的方式出错
在学习处理异常之前,我们先看下如何引发异常以及创建自己的异常类型:
(1)raise语句
为了引发异常。可以使用一个类(Exception的子类)或者实力参数调用raise语句:
>>> raise Exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception
>>> raise Exception('hello word')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: hello world
第一个例子raise Exception引发了一个没有任何错误信息的异常。后一个例子添加了错误信息hello world.
内建的异常类有很多,这里我们看下一些最重要的异常类:
类名 描述
Exception 所有异常的基类
AttributeError 特性引用或者赋值失败时引发
IOError 试图打开不存在文件时候引发
IndexError 在使用序列中不存在的索引时引发
KeyError 在使用映射中不存在的键时引发
NameError 在找不到名字(变量)时引发
SyntaxError 在代码为错误的形式时引发
TypeError 在内建操作或者函数应用错误类型对象时引发
ValueError 在内建操作或者函数应用正确类型的对象,但是该对象使用不适合的 值时引发
ZeroDivisionError 在除法或者模操作的第二个参数为0时引发
(2)自定义异常类
尽管内建的异常类已经包含了大部分的情况,但是有时候还是需要创建自己的类,那么如何创建自己的类呢,就像其它类一样,只是要确保是从Exception类继承:
class SomeCustomException(Exception): pass
如果你愿意,你也可以向你的异常类中添加方法。
捕捉异常
前面提到过,关于异常最有意思的地方就是可以处理它们(通常叫做诱捕或者捕捉异常)。这个功能可以使用try/except语句来实现。假设创建了一个让用户输入两个数,然后进行相加的程序:
x= input('Enter the first number:')
y= input('Enter the second number:')
print x/y
加入用户输入0作为第二个数:
Enter the first number:10
Enter the second number:0
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print x/y
ZeroDivisionError: integer division or modulo by zero
为了捕捉异常并且做出一些错误处理(本例中只是输出一些友好信息),可以这样:
try:
x= input('Enter the first number:')
y= input('Enter the second number:')
print x/y
except ZeroDivisionError:
print 'hello word'
Enter the first number:1
Enter the second number:0
hello word
如果捕捉到了异常,但是又想重新引发它,那么可以使用不带参数的raise。
举个例子,看看这么做的用处:考虑下一个能“屏蔽”ZeroDivisionError的计算器类。如果这个行为被激活,那么计算机就会打印错误信息,而不是让异常传播。如果在与程序内部使用引发异常又会更好,所以”屏蔽“机制就可以关掉了,下面是这样一个类的代码:
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
运行一下:
print calculator.calc('10/0')
Traceback (most recent call last):
File "./test.py", line 14, in <module>
print calculator.calc('10/0')
File "./test.py", line 7, in calc
return eval(expr)
File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
calculator.muffled=True
print calculator.calc('10/0')
Division by zero is illegal
None
不知一个except子句
如果在上面的那个程序里第二个数字输入非字符类型的值,那么
4000
就会产生第二个异常:
Enter the first number:1
Enter the second number:'a'
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print x/y
TypeError: unsupported operand type(s) for /: 'int' and 'str'
因为except子句值寻找ZeroDivisionError异常,这次的错误就溜过了检查并导致程序终止,为了捕捉这个异常,我们可以在try/except语句后面加上里一个except子句:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except ZeroDivisionError:
print 'a'
except TypeError:
print 'b'
用一个块捕捉两个异常
如果需要用一个块捕捉多个类型异常,那么可以将它们作为元组列出,像下面这样:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except (ZeroDivisionError,TypeError):
print 'hello world'
[root@localhost python]# ./test.py
Enter the first number:1
Enter the second number:'a'
hello world
捕捉对象
如果希望在excep子句中访问异常对象本身,可以使用两个参数(注意,就算捕捉到多个异常,也只需向except子句提供一个参数——一个元组),比如想让程序继续运行,但是又因为某种原因想记录下错误(比如只是打印给用户看),这个功能就很有用:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except (ZeroDivisionError,TypeError),a:
print a
[root@localhost python]# ./test.py
Enter the first number:1
Enter the second number:'a'
unsupported operand type(s) for /: 'int' and 'str'
真正的全捕获
就算程序可以处理好几种类型的异常,但是有些异常还是会从眼皮地下溜走,但是如果想用一段代码捕获所有的异常,就可以在except子句中忽略所有的异常类:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except:
print 'hello world'
警告:这样的全捕获是危险的,因为它会隐藏程序员未想到并且未做好准备处理的错误。这时还是使用except Exception,e这样好点
万事大吉
可以像条件和循环语句那样,给try/except语句加个else子句:
while True:
try:
x=input('Enter the first number:')
y=input('Enter the second number:')
print x/y
except Exception,e:
print e
else:
break
[root@localhost python]# ./test.py
Enter the first number:1
Enter the second number:0
integer division or modulo by zero
Enter the first number:''^[[Da
invalid syntax (<string>, line 1)
Enter the first number:'a'
Enter the second number:'a'
unsupported operand type(s) for /: 'str' and 'str'
Enter the first number:10
Enter the second number:2
5
最后.......
最后是finally子句,它可以用来在可能的异常后进行清理,它和try子句联合使用:
x=None
try:
x=1/0
finally:
print 'clean up'
del x
[root@localhost python]# ./test.py
clean up
Traceback (most recent call last):
File "./test.py", line 5, in <module>
x=1/0
ZeroDivisionError: integer division or modulo by zero
finally子句肯定会被执行,不管try子句中是否发生异常的。
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法