关闭

《Python基础教程》学习笔记 Chp8 异常

标签: python
198人阅读 评论(0) 收藏 举报
分类:

1.什么是异常
Python用异常对象(exception object)来表示异常情况。遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(traceback)终止信息。例:

>>> 1/0
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

2.按自己的方式出错
raise语句
为了引发一个异常,可以使用一个类(应该是Exception的子类)或者实例参数调用raise语句。使用类时,程序会自动创建一个类的实例。例:

>>> raise Exception
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
Exception
>>> raise Exception("can't be zero")
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
Exception: can't be zero

第一个例子raise Exception引发了一个没有任何有关错误信息的普通异常。后一个例子中,则添加了错误信息“can’t be zero”。
一些内建异常
Exception:所有异常的基类
AttributeError:特性应用或赋值失败时引发
IOError:试图打开不存在文件(包括其他情况)时引发
IndexError:在使用序列中不存在的索引时引发
KeyError:在使用映射中不存在的键时引发
NameError:在找不到名字(变量)时引发
SyntaxError:在代码为错误形式时引发
TypeError:在内建操作或者函数应用于错误类型的对象时引发
ValueError:在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时引发
ZeroDivisionError:在除法或者模除操作的第二个参数为0时
自定义异常类
跟创建其他类一样,只要确保从Exception类继承(不管是间接的还是直接的)即可。例:

>>> class SomeCustomException(Exception):
...     pass
... 

3.捕捉异常
使用try/except语句来处理异常。
使用try/except捕获异常。例:

>>> try:
...     x = input("input a number : ")
...     y = input("input another number : ")
...     print x/y
... except ZeroDivisionErro:
...     print "the second number can't be zero !"
...
input a number : 10
input another number : 0
Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
NameError: name 'ZeroDivisionErro' is not defined

即使已经捕获了异常,但是又想重新引发它,就那么可以调用不带参数的raise。例:

>>> class MuffledCalculator:
...     muffled = False
...     def cal(self, expr):
...         try:
...             return eval(expr)
...         except ZeroDivisionError:
...             if self.muffled:
...                 print 'Division by zero is illegal !'
...             else:
...                 raise
...             
>>> calculator = MuffledCalculator()
>>> calculator.cal('10/2')
5
>>> calculator.cal('10/0')
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 5, in cal
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> calculator.muffled = True
>>> calculator.cal('10/0')
Division by zero is illegal !

上例中通过muffled的值打开和关闭了屏蔽机制。
用一个块捕捉多个异常
如果需要用一个块捕捉多个类型异常,那么可以将它们作为元组列出。例:

>>> try:
...     x = input("input a number : ")
...     y = input("input another number : ")
...
...     print x/y
... except (ZeroDivisionErro, TypeError, NameError):
...     print 'your numbers were bogus ....'

捕捉对象
如果希望在except子句中访问异常对象本身,可以使用两个参数(注意:就算要捕捉到多个异常,也只需向except子句提供一个参数——一个元组)。例:

>>>  try:
...     x = input("input a number : ")
...     y = input("input another number : ")
...
...     print x/y
... except (ZeroDivisionErro, TypeError, NameError), e:
...     print e

注:在python3.0中,except子句会被写作except(ZeroDivisionErro, TypeError, NameError) as e
真正的全捕捉
如果想用一段代码捕捉所以异常,那么可以在except子句中忽略所有的异常类。例:

>>>  try:
...     x = input("input a number : ")
...     y = input("input another number : ")
...
...     print x/y
... except :
...     print 'something is wrong !'

注:像上例中的这种捕捉方式比较危险,因为他会隐藏所有程序员未想到的并且未做好准备处理的错误。它同样会捕捉用户终止执行的Ctrl+C企图,以及用sys.exit函数终止程序的企图等。这时用except Exception, e会更好些,或者对异常对象e进行一些检查。
万事大吉
有些情况中,没有坏事发生时执行一段代码是很有用的,可以相对条件和循环语句那样,给try/except语句加个else子句,如果主try块中没有异常发生,else子句就会被执行。例:

>>> try:
...     print 'A simple task'
... except :
...     print 'What? Something went wrong !'
... else:
...     print 'Ah ......It went as planned !'
...     
A simple task
Ah ......It went as planned !

可以使用else子句实现循环。例:

>>> try:
...     x = input("input a number : ")
...     y = input("input another number : ")
...     print x/y
... except :
...     print 'invalid input. Please try again !'
... else:
...     break

注:这里的循环只有在没有异常的情况下才会退出(有else子句中的break语句退出)。只要有错误发生,程序会不断要求重新输入。
最后………
finally子句,它可以用来在可能的异常后进行清理。它和try子句联合使用。例:

>>> x = None
>>> try:
...     x =1/0
... finally:
...     print 'Cleaning up.....'
...     del x
...     
Cleaning up.....
Traceback (most recent call last):
  File "<interactive input>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> x
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
NameError: name 'x' is not defined

注:上例中,finally子句肯定会被执行,不管try子句是否发生异常。
还可以在同一条语句中组合使用try、except、finally和else(或者其中三个)。例:

>>> try:
...     x =1/0
... except NameError, e:
...     print 'unknown variable !'
... else:
...     print 'That were well !'
... finally:
...     print 'Cleaning up.....'
...     
Cleaning up.....
Traceback (most recent call last):
  File "<interactive input>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero

4.异常和函数
异常和函数可以一起工作。如果异常在函数内引发而不被处理,它就会传播至函数调用的地方。如果那里也没有处理异常,它就会继续传播,一直到达主程序,如果那里也没有处理异常 ,程序会带着栈淙淙终止。例:

>>> def faulty():
...     raise Exception('Somethins is wrong !')
... 
>>> def ignore_faulty():
...     faulty()
...     
>>> def handle_exception():
...     try:
...         faulty()
...     except:
...         print 'Exception handled !'
...         
>>> ignore_faulty()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 2, in ignore_faulty
  File "<interactive input>", line 2, in faulty
Exception: Somethins is wrong !
>>> handle_exception()
Exception handled !

5.本章的新函数
warnings.filterwarnings(action, …..) : 用于过滤警告

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9306次
    • 积分:355
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论