PythonTip >> 博文 >> python

python进阶八_警告和异常

zihua 2014-05-14 15:05:58 点击: 859 | 收藏


心情有点纠结,怎么说呢,倒不是因为其他学习上的事情,反而是因为生活上狗血的剧情逼着人偏离,渐行渐远,人跟人之间有误会也是正常的,可能是因为交流不够,彼此不够了解吧,希望能尽快度过这一段纠结的日子,简单的生活,慢慢的品味,细细的思考。

最近一段时间,因为需要,借阅了一本 Python Cookbook ,发现这本书在很多方面介绍的都很不错,比如一些系统管理, web ,分布式编程,数据持久化等等这些方面。但是却没有发现详细的关于错误和异常的一些介绍,本着作死的态度打算好好研究一下。

首先,照例,我们先来看一段示例程序:


首先,我们这里出现的不是异常,而是另一个我们经常遇到的非致命警告 warning, 主要是向用户提供非致命警告,指出运行一个程序时遇到的问题,通常来说,我们最好是在程序中不要出现这些东西,否则我们就需要从新审视我们的代码了。

一. Warning--- 非致命警告

警告使用的是内置异常类 Warning 的子类进行分类,通常需要根据过滤器( filter )设置来处理。过滤器一般包括, Action Message,Category,Module Line number. 也可以这么理解,这里面的消息 Message 部分通常是一个匹配警告文本的正则表达式,类别 Catregory 是一个异常类的名称,模块 Module 包含一个正则表达式,要与生成警告的模块名匹配,行号 Line Number 可以改变在一个警告出现时的处理

每当生成一个警告时,都需要将其与注册过的过滤器比较,第一个匹配的过滤器将控制这个警告采取的动作,否则采取默认的动作,其实本质流程上会发现与 Exception 异常处理如出一辙,看一下常见的过滤器动作:

动作

含义

error

将警告提升为异常

ignore

忽略警告

always

总是抛出警告

default

从各个位置第一次生成警告时输出警告

module

从各个模块第一次生成警告时输出警告

once

第一次生成警告时输出警告

1. 模式过滤

简单的过滤如示例中的 show_warning_by_filtering(), 但是想要通过编程按照更复杂的规则进行过滤就需要使用 filterwarning() ,比如,需要根据消息文本的内容过滤,可以提供一个正则表达式作为参事。如示例中的 show_pattern_filter(), 模式包含‘ do not ’具体的消息中使用了‘ Do not ’,正则表达式被编译为不区分大小写的匹配,故这个模式会匹配。当然,同样的匹配也适用于源模块名,可以将模块名作为模式传至 module 参数,抑制来自 copy 模块的所有消息,如下所示:


当然,我们也可以限定只抑制某一行上的警告,如下所示:


2.重复警告

默认情况,大多数警告只会在给定位置第一次出现时才会输出,但是假如我们的程序里面出现了警告,我们改完之后发现后面还有一个相同的警告,这个时候就会有不知道什么时候是个头的错觉,最直接的办法就是在每一个出现警告的地方我们就给他来一个警告,最起码我们能做到心里有数,如下所示:


3.警告定向输出

一般情况下,警告都会输出到 sys.stderr ,我们可以通过替换 warning 模块中的 showwarning() 函数来改变这个行为,如下所示:


稍微注意下:这里的 UserWarning 是一种警告类型,来自用户代码的警告的基类,还有一些其他的类型,比如 :

Warning----- 所有警告的基类

DeprecationWarning---- 用于不再维护的特性

PendingDeprecationWarning---- 用于很快会废弃的特性

SyntaxWarning--- 用于有问题的语法

RuntimeWarning---- 用于运行时可能导致问题的事件

FutureWarning---- 关于将来语言或者库中可能的改变的有关警告

ImportWarning   关于导入模块时出现的问题的警告

UnicodeWarning--- 关于 Unicode 文本中的问题的警告

二.Exception---- 内置异常类

1.异常基类

BaseException

所有异常的基类,实现了基类的逻辑,可以使用 str() 由传入构造函数的参数创建异常的一个串表示

Exception:

有些异常不会导致退出正在运行的应用, Exception 是这些所有异常的基类,用户定义的所有异常应当都是用其作为基类

StandardError:

标准库中使用的内置异常的基类

ArithmeticError

与数学相关的错误的基类

LookupError

无法找到某个对象时产生的错误的基类

EnvironmentError

来自 Python 外部(操作系统,文件系统等)错误的基类

2.常见的异常

这里,我们仅仅以 AssertionError 为例, AssertionError 是由一个失败的 assert 语句产生,断言在库中一般很常见,通常用来对传入参数的限制,通过类似 failif() 等方法, AssertionError 还可以用在 unittest 模块创建的自动测试中,运行的自动测试套件的程序会监视 AssertionError 异常,作为测试失败的一个特殊提示,如下所示:


当然除此之外还有很多异常,如下:

AttributeError: 当一个属性引用或赋值失败时,会产生

EOFError :对于类似 input 或者 raw_input 这样的内置函数,如果在遇到输入流末尾之前没有读到任何数据,会产生

FloatingPointError :这个错误由导致错误的浮点操作产生,前提是已经打开了浮点异常控制 (fpectl), 启用 fpectl 时,要求编译解释器提供  with-fpectl 标志,但是标准文档中不提倡使用 fpectl

IOError: 输入或输出失败时会产生,如磁盘满了,输入文件不存在等等

ImportError: 无法导入一个模块或者模块中的一个成员时会产生该异常

IndexError: 如果一个序列引用越界,就会产生 IndexError

KeyError: 如果没有找到一个值作为字典的键,会产生异常

KeyBoardInterrupt: 用户按下 Ctrl-C( 或者 Delete) 终止一个正在运行的程序时,会产生

MemoryError :如果一个程序用尽了所有内存,而且可以恢复,会产生

NameError: 如果代码引用了一个名字,而当前作用域中不存在这个名字,会产生

NotImplementedError: 用户自定义的基类可能产生 NotImplementedError ,来指示一个方法或者行为需要子类定义

OSError: 一个操作系统级别函数返回错误时会产生 OSError

OverflowError: 当一个算术运算超出变量类型的界限时,会产生

RefernceError:

使用一个 weakref 代理访问已经被垃圾回收的对象时,会产生

RuntimeError: 如果没有其他更特定的异常可用,就要使用 RuntimeError 异常

SyntaxError: 当解释器无法解释程序的时候,会产生

SystemError: 如果错误发生在解释其本身,会产生

SystemExit: 当调用 sys.exit() 会产生

TypeError: 结合对象或者在对象上调用函数时,如果对象类型不正确会产生

UnboundLocalError: 一种 NameError, 特别针对局部变量名

UnicodeError:ValueError 的一个子类,出现 Unicode 问题时产生

ValueError: 如果一个函数接收到的值类型正确,但是值不合法

ZeroDivisionError:0 做分母时抛出

特别提醒:关于为什么要了解异常呢,首先在程序中我们可能会经常碰到,但是最重要的是这对以后我们编写程序,调试程序提供了有力的帮助,针对错误信息,可以立即判断出什么地方出了问题,这才是最重要的地方

原文链接:http://www.tuicool.com/articles/7FFnmu

作者:zihua | 分类: python | 标签: python | 阅读: 859 | 发布于: 2014-05-14 15时 |