基于字符串的异常

python在2.6之前可以使用字符串来定义异常,并且是通过对象标识符来匹配的(即通过is 而不是==)

myexc = "My excetion string"
try:
raise myexc
except myexc:
print('caught')

基于类的异常

字符串定义的异常非常简单,但是并不容易维护。使用类定义的异常通过超类关系进行匹配,只要except列举出来的异常的类或者任何超类名,引发的异常都会匹配到。此外,类的异常还支持异常状态信息,可以让异常参与继承层次。

类异常的例子

class General(Exception):pass
class Special1(General):pass
class Special2(General):pass
def raise0(): raise General()
def raise1(): raise Special1()
def raise2(): raise Special2() for fun in (raise0,raise1,raise2):
try:
fun()
except General:
import sys
print('caught',sys.exc_info()[])

运行的结果如下

caught <class '__main__.General'>
caught <class '__main__.Special1'>
caught <class '__main__.Special2'>

将excep的部分化为下面的内容,结果一样,sys.exc_info将在下一章讲到。

    except General as x:
print('caught:',x.__class__)

类异常的另一个例子

假如我们维护了一个mathlib.py的库,原本定义了两个异常Divzero和Oflow,

class Divzero(Exception): pass
class Oflow(Exception): pass
def func():
raise Divzero()

当别人使用我们的库的时候我们可以进行异常处理:

import mathlib
try:
mathlib.func()
except (mathlib.Divzero,mathlib.Oflow):
'''do what you want to do '''

但是,当我们维护我们的库的时候新加入一个异常Uflow的时候,别人必须修改他们的代码,这样在大型程序当中非常的不好。所以我们尝试把我们库中的代码写成下面的形式:

class NumErr(Exception):pass
class Divzero(NumErr): pass
class Oflow(NumErr): pass
'''其余的异常'''
def func():
raise Divzero()

别人引用的时候只需要写成下面的形式即可:

import mathlib
try:
mathlib.func()
except mathlib.NumErr:
'''do what you want to do '''

无论我们增加多少个异常的类,别人的代码都不需要进行修改。

内置Exception类

-BaseException类:异常的顶级根类,不可以被用户定义的类直接继承(应当使用Exception)。它提供了子类所继承的默认的打印和状态保持行为。

-Exception类:与应用相关的异常的顶层根超类,是BaseExcption的一个直接子类,并且是所有其他内置异常的超类,除了系统退出事件类以外(SystemExit、KeyboardInterrupt和GeneratorExit)。

In [2]: Exception.__bases__
Out[2]: (BaseException,)
In [3]: SystemExit.__bases__
Out[3]: (BaseException,)

-ArithmeticeError 所有数值错误的超类

In [4]: ArithmeticError.__bases__
Out[4]: (Exception,)

-OverflowError 识别特定的数值错误的子类

In [5]: OverflowError.__bases__
Out[5]: (ArithmeticError,)

从上面的代码可以看出,python中的异常总是这样的进行继承的

默认打印和状态

python内置异常提供默认的打印方法:传递给这些类的任何构造函数参数都会保存在实例的args元祖属性中,并且当打印该实例的时候自动显示。这就说明了为什么传递给内置异常类的参数会出现在出错消息中。

输入:

raise IndexError

输出:

Traceback (most recent call last):
File "D:\application\eclipse\workspace\yichang\c3\t6.py", line 1, in <module>
raise IndexError
IndexError

输入:

raise IndexError('nihao')

输出:

Traceback (most recent call last):
File "D:\application\eclipse\workspace\yichang\c3\t6.py", line 1, in <module>
raise IndexError('nihao')
IndexError: nihao

输入:

i = IndexError('nihao')
print(i.args)

输出:

('nihao',)

同样,我们自己定义的类也是如此,因为他们继承了内置超类中存在的构造很熟和显示方法

输入:

class MyErr(Exception):pass

try:
raise MyErr('nihao')
except MyErr as x:
print(x,x.args)

输出:

nihao ('nihao',)

输入:

class MyErr(Exception):pass

try:
raise MyErr('nihao','wohao','dajiahao')
except MyErr as x:
print(x,x.args)

输出:

('nihao', 'wohao', 'dajiahao') ('nihao', 'wohao', 'dajiahao')

为什么输出x和x.args是一样的?因为,这是由于__str__来决定的,直接输出了str(args)。

定制我们自己的打印显示:

其实,主要是修改我们定制的类中的__str__和__repr__方法,而__str__又是主要的。

下面我们为我们自己定义的类当中重定义__str__方法:

class MyErr(Exception):
def __str__(self):
return 'this is MYErr Exception' try:
raise MyErr('nihao','wohao','dajiahao')
except MyErr as x:
print(x)

输出: this is MYErr Exception

改造构造方法

class FormatError(Exception):
def __init__(self,line,file):
self.line = line
self.file = file try:
raise FormatError(2,'nihao')
except FormatError as x:
print(x.line,x.file)
print(x.args[0],x.args[1])

通过改造构造方法,可以体统更多的细节,但是args还是可以使用的,输出结果如下:

2 nihao
2 nihao

定义一些方法,在处理器内部执行

class FormatError(Exception):
logfile = r'log.txt'
def __init__(self,line,file):
self.line = line
self.file = file
def logger(self):
log = open(self.logfile,'a')
print('error at line:',self.line,'file:',self.file,file=log) try:
raise FormatError(11,'t7.txt')
except FormatError as x:
x.logger()

该异常定义了出错的时候存入特定文件夹的功能,当捕获异常的时候,执行logger方法

执行后在log.txt中有如下语句: error at line: 11 file: t7.txt


总结:这一章我们其实是明确了,异常主要是通过类来实现的,在try语句中,捕捉其超类就会捕捉这个类,以及类树中超类下的所有子类。

《python学习手册》第34章 异常对象的更多相关文章

  1. Python学习手册(第4版) - 专业程序员的养成完整版PDF免费下载_百度云盘

    Python学习手册(第4版) - 专业程序员的养成完整版PDF免费下载_百度云盘 提取码:g7v1 作者简介 作为全球Python培训界的领军人物,<Python学习手册:第4版>作者M ...

  2. Python学习手册(第4版)PDF高清完整版免费下载|百度云盘

    Python学习手册(第4版)PDF高清完整版免费下载|百度云盘 提取码:z6il 内容简介 Google和YouTube由于Python的高可适应性.易于维护以及适合于快速开发而采用它.如果你想要编 ...

  3. 《Python学习手册 第五版》 -第14章 迭代和推导

    承接上一章for循环的讲解,迭代和推导,是对for循环的一种深入的探索和扩展 本章重点内容 1.迭代 1)什么是迭代?都有哪些分类 2)常规的使用方法 3)多遍迭代器VS单遍迭代器 2.列表推导 1) ...

  4. 《Python学习手册 第五版》 -第13章 while循环和for循环

    上一章已经讲过if条件语句,这章重点是循环语句:while.for 本章的重点内容 1.while循环 1)一般形式 2)break.continue.pass和循环的else 2.for循环 1)一 ...

  5. 《Python学习手册 第五版》 -第11章 赋值、表达式和打印

    上一章对Python的语句和语法已经进行了基本的说明,接下来就是每个章节的详细说明,本章的主要内容就是标题中涵盖的三点:赋值语句.表达式语句.打印语句 本章重点内容如下: 1.赋值语句 1)赋值语句的 ...

  6. 《Python学习手册 第五版》 -第10章 Python语句简介

    前面在开始讲解数据类型的时候,有说过Python的知识结构,在此重温一下 Python知识结构: 程序由模块组成 模块包含语句 语句包含表达式 表达式创建并处理对象 关于知识结构,前面已经说过我自己的 ...

  7. 《Python学习手册 第五版》 -第18章 参数

    在函数的定义和调用中,参数是使用最多喝最频繁的,本章内容就是围绕函数的参数进行讲解 本章重点内容如下: 1.参数的传递 1)不可变得参数传递 2)可变得参数传递 2.参数的匹配模式 1)位置次序:从左 ...

  8. 《Python学习手册 第五版》 -第15章 文档

    本章主要介绍Python中的文档,会通过多种方式来说明,如果查看Python自带文档和其他参考的资料 本章重点内容 1.#注释:源文件文档 2.dir函数:以列表显示对象中可用的属性 3.文档字符串 ...

  9. 《Python学习手册 第五版》 -第16章 函数基础

    前面的章节讲解的是一些基础数据类型.基本语句使用和一些文档查看的内容,这些都是一些基础,其实还谈不上入门,只有了解了函数,才算入门 函数是编程里面使用最多的也是最基本的程序结构, 本章重点内容 1.函 ...

随机推荐

  1. Java并发编程(二)

    1.Lock接口                                                        在Lock接口出现之前,Java程序是靠synchronized关键字实 ...

  2. MGR_ERROR 3092 (HY000): DROP DATABASE failed;

    start group_replication;时报以下错: ERROR 3092 (HY000): DROP DATABASE failed; some tables may have been d ...

  3. juery给所有ID属性相同的div绑定一个事件

    案例: <div id="div1">内容</div> <div id="div1">内容</div> < ...

  4. spring mvc 自定义编辑器

    起始知识: Java标准的PropertyEditor的核心功能是将一个字符串转换为一个Java对象,以便根据界面的输入或配置文件中的配置字符串构造出一个JVM内部的java对象. 如何注册自定义的属 ...

  5. What does “=>” mean in import in scala?(转自StackOverflow问答)

      As others have mentioned, it's an import rename. There is however one further feature that proves ...

  6. popstate实现history路由拦截,监听页面返回事件

    1.当活动历史记录条目更改时,将触发popstate事件. 如果被激活的历史记录条目是通过对history.pushState()的调用创建的, 或者受到对history.replaceState() ...

  7. SVM资料

    解释SMO算法比较好的文档 http://wenku.baidu.com/view/aeba21be960590c69ec3769e.html 参考博客: http://myjuno.blogbus. ...

  8. PHP学习笔记之数组游标操作

    数组有N个单元,同时只能操作一个单元.比如循环时,只能一个一个单元读取他的值. 那么数组是怎么记住刚才读取的是哪个单元,接着读取下个单元的呢? 在数组内部,有一个指针,指针指向某一个单元. 每循环一个 ...

  9. ntp 控制报文

    //make the procedure into block//2014.7.23 OK//#include "CSocket.h" #define NTP_SERVER_IP ...

  10. [BZOJ3672][Noi2014]购票 斜率优化+点分治+cdq分治

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1749  Solved: 885[Submit][Status][ ...