《python学习手册》第34章 异常对象

基于字符串的异常

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()[0])

运行的结果如下

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语句中,捕捉其超类就会捕捉这个类,以及类树中超类下的所有子类。

时间: 2024-08-07 08:37:59

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

python学习手册——1介绍python对象类型

在python ,数据以对象的形式出现--无论是python提供的内置对象,还是使用python或是像C扩展库这样的扩展语言工具创建的对象.尽管在以后才能确定这一概念,但对象无非是内在中的一部分,包含数值和相关操作的集合. 由于对象是python 最基本的概念,从这一章开始我们将会全面地体验python的内置对象类型. python程序可以分解成模块,语句,表达式以及对象,如下所示: 1.程序由模块构成 2.模块包含语句 3.语句包含表达式 4.表达式建立并处理对象 为什么使用内置类型 1.内置

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

上一章对Python的语句和语法已经进行了基本的说明,接下来就是每个章节的详细说明,本章的主要内容就是标题中涵盖的三点:赋值语句.表达式语句.打印语句 本章重点内容如下: 1.赋值语句 1)赋值语句的特点(注意事项) 2)赋值语句的形式:基本形式.元组及列表解包赋值.序列赋值.扩展的序列解包.多目标赋值.增量赋值 3)变量命名规则 2.表达式语句 1)常见的表达式语句 2)表达式语句和原位置修改 3.打印操作 1)调用形式 2)应用示例 以下是针对以上重点内容的详细说明 1.赋值语句 1)赋值语

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

前面的章节讲解的是一些基础数据类型.基本语句使用和一些文档查看的内容,这些都是一些基础,其实还谈不上入门,只有了解了函数,才算入门 函数是编程里面使用最多的也是最基本的程序结构, 本章重点内容 1.函数 1)什么是函数? 2)为什么使用函数? 2.编写函数 1)函数的基本格式 2)定义和调用函数 3)函数的多态.局部变量 接下来针对本章重点,展开详细的说明 1.函数 1)什么是函数? 这里没有严格的定义,用通俗易懂的方式来说: 函数就是将一些语句集合在一起的组件,从而让他们能够不止一次的在程序中

《Python学习手册 第五版》 -第12章 if测试和语法规则

本章节的内容,主要讲解if语句,if语句是三大复合语句之一(其他两个是while和for),能处理编程中大多数逻辑运算 本章的重点内容如下: 1.if语句的基本形式(多路分支) 2.布尔表达式 3.if三元表达式 以下是针对重点内容的详细说明 1.if语句的基本形式 if语句是根据测试结果,从一些备选的操作中做出选择的语句,也就是说要先计算测试结果,再选择做什么,基本形式如下: if test1: statements1 elif test2: statements2 else: stateme

Python学习手册笔记

之前为了编写一个svm分词的程序而简单学了下Python,觉得Python很好用,想深入并系统学习一下,了解一些机制,因此开始阅读<Python学习手册(第三版)>.如果只是想快速入门,我在这里推荐了几篇文章,有其他语言编程经验的人简单看一看就可以很快地开始编写Python程序了. 黑体表示章节, 下划线表示可以直接在原文对应位置查到的专有技术名词. 原书配套答案请到http://www.hzbook.com/Books/4572.html下载,简单注册即可. 第三章 如何运行程序 impor

《Python学习手册》读书笔记【转载】

转载:http://www.cnblogs.com/wuyuegb2312/archive/2013/02/26/2910908.html 之前为了编写一个svm分词的程序而简单学了下Python,觉得Python很好用,想深入并系统学习一下,了解一些机制,因此开始阅读<Python学习手册(第三版)>.如果只是想快速入门,我在这里推荐了几篇文章,有其他语言编程经验的人简单看一看就可以很快地开始编写Python程序了. 黑体表示章节, 下划线表示可以直接在原文对应位置查到的专有技术名词. 原书

[读书]Python学习手册--属性管理1

属性管理-特性 一般开发这不必关心属性的实现,对工具的构建这来说,了解这一块对API的灵活性有帮助. 大多数情况下,属性位于对象自身之中,或者继承自对象所派生自的一个类. ----python学习手册 property property(fget=None, fset=None, fdel=None, doc=None) -> property attribute fget is a function to be used for getting an attribute value, and

《Python 学习手册》笔记 1

今天看了 Udacity 的 iOS 学习路线介绍,作者的看法是,最好先学习 Swift,而不是 Objective-C,原因一方面是 Swift 要简单一些,另一方面是因为 Apple 打算用 Swift 作为将来的官方语言取代 OC. 大学里,编程语言课程就是 C 和 C++.我不知道这是谁定的,也许他们有足够充分的理由.但是对于大多数人来说,这两个语言——一个太底层,一个太复杂)其实不见得那么重要.还不如学学 Ruby 和 Python 这样的抽象度更高的解释性语言,易于使用,而且内置了强

读书分享全网学习资源大合集,推荐Python学习手册等三本书「01」

0.前言 在此之前,我已经为准备学习python的小白同学们准备了轻量级但超无敌的python开发利器之visio studio code使用入门系列.详见 1.PYTHON开发利器之VS Code之初识.简介.安装.中文 2.PYTHON开发利器之VS Code 主题.界面美化.快捷键.编辑器技巧 3.PYTHON开发利器之VS Code 常用插件介绍 4.PYTHON开发利器之使用VS Code进行python程序开发 5.1.PYTHON开发利器之使用VS Code+Git进行python