基于字符串的异常

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. USB基础介绍

    (转)USB (Universal Serial Bus) 全文地址:http://vlewang.blog.163.com/blog/static/105878151201032804347546/ ...

  2. python使用unittest模块selenium访问斗鱼获取直播信息

    import unittest from selenium import webdriver from bs4 import BeautifulSoup as bs class douyu(unitt ...

  3. 【bzoj5050】【bzoj九月月赛H】建造摩天楼

    讲个笑话,这个题很休闲的. 大概是这样的,昨天看到这个题,第一眼星际把题目看反了然后感觉这是个傻逼题. 后来发现不对,这个修改一次的影响是很多的,可能导致一个数突然可以被改,也可能导致一个数不能被改. ...

  4. [转载]Windows服务编写原理及探讨(1)

    有那么一类应用程序,是能够为各种用户(包括本地用户和远程用户)所用的,拥有用户授权级进行管理的能力,并且不论用户是否物理的与正在运行该应用程序的计算机相连都能正常执行,这就是所谓的服务了. (一)服务 ...

  5. shell视频

    本帖最后由 Shell_HAT 于 2014-04-18 16:51 编辑 尚观全套RHCE视频http://pan.baidu.com/s/1pJvzVR1 马哥网络班-中级视频内容http://p ...

  6. kNN算法笔记

    kNN算法笔记 标签(空格分隔): 机器学习 kNN是什么 kNN算法是k-NearestNeighbor算法,也就是k邻近算法.是监督学习的一种.所谓监督学习就是有训练数据,训练数据有label标好 ...

  7. Python基本语法[二]

    Python基本语法 1.定义变量:  代码正文: x= y= z=x+y 代码讲解: 2.判断语句:  代码正文: score= : print("你真棒") print(&qu ...

  8. ScrureCRT访问CentOS时出现乱码的解决办法

    1.  ScrureCRT访问CentOS时,出现乱码. 登陆后,输入日历命令:cal 输出日历带有乱码的结果: 2.  查看当前系统的语言. 输入命令:echo $LANG 输出:zh_CN.UTF ...

  9. vue使用路由判断是否登录

    router.beforeEach((to, from, next) => { // console.log('to:' + to.path) if (to.path.startsWith('/ ...

  10. ApplicationContext中getBean详解

    在org.springframework.context包中有一个接口叫 applicationContext applicationContext中有一个getBean方法,此方法继承之BeanFa ...