基于字符串的异常

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. Linux 编译 apr-util 时报错

    前言 Apache 2.4 以后的版本不再自带 APR 库(Apache Portable Runtime,Apache 可移植运行库),所以在安装 Apache 之前需要手动下载安装 APR 库. ...

  2. (转)USB 基本知识

    USB的重要关键字: 1.端点:位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有惟一的确定地址,有不同的传输特性(如输入端点.输出端点.配置端点.批量传输端点) ...

  3. iTextSharp之pdfRead(两个文件文本内容的比较,指定页数的pdf截取,水印的添加)

    using iTextSharp.text; using iTextSharp.text.pdf; using iTextSharp.text.pdf.parser; using System; us ...

  4. 解决UC手机字体变大的有关问题

    解决UC手机字体变大的问题 UC手机浏览器在识别到页面文字很多的情况下会自动放大字体优化阅读体验,如果要关闭这个功能需要在网页头部添加: <meta name="wap-font-sc ...

  5. JavaScript 实现数组去重

    JavaScript 实现数组去重 演示Demo 数组去重 // 方法一 function unique1(a) { var res = []; for (var i = 0, len = a.len ...

  6. laravel windows安装(composer)

    1.安装composer参考windows 安装tp5 composer方式 2.先配置好本地虚拟域名,在cmd里面切换到网站根目录 ... 3.安装成功之后,在浏览器输入已配置的虚拟域名我的是,la ...

  7. ie6 css 返回顶部图标固定在浏览器右下角

    比较常用记录一下. #e_float{ _position:absolute; _bottom:auto; _right:50%; _margin-right:-536px; _top:express ...

  8. Docker CentOS 网段与公司网段冲突

    参考文章: <Docker修改默认地址172.17.0.1> 在公司内网的一个虚拟服务器(CentOS 7)安装Docker后,发现网段172.18.0.1和172.17.0.1与公司内部 ...

  9. 湖南大学ACM程序设计新生杯大赛(同步赛)L - Liao Han

    题目描述 Small koala special love LiaoHan (of course is very handsome boys), one day she saw N (N<1e1 ...

  10. export导出.xls时,在火狐的情况下出现表名乱码的情况的解决方案

    response.setContentType("application/octet-stream; charset=utf-8");fileName = exportDataDt ...