python错误和异常

1. 错误:

      从软件方面来说,错误是语法或是逻辑上的。语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译。这些错误必须在程序执行前纠正。

      当程序的语法正确后,剩下的就是逻辑错误了。逻辑错误可能是由于不完整或是不合法的输入所致;在其它情况下,还可能是逻辑无法生成,计算,或是输出结果需要的过程无法执行。这些错误通常分别被称为错误和范围错误。

      当 Python 检测到一个错误时, 解释器就会指出当前流已经无法继续执行下去. 这时候就出现了异常.
2. 检测和处理异常

异常可以通过try语句来检测,任何try语句块里的代码都会被监测,检查有无异常发生。

try:
try_suite # watch for exceptions here 监控这里的异常
except Exception[, reason]:
except_suite # exception-handling code 异常处理代码
reason是可选的,可以把相应的错误的理由放到reason里面输出。


try语句有两种主要形式:try-except和try-finally。这两个语句是互斥的,也就是说你只能使用其中的一种,一个try语句可以对应一个或多个except子句,但是只能对应一个finally子句,或是一个try-except-finally复合语句。

你可以使用try-except语句检测和处理异常。你也可以添加一个可选的else子句处理没有探测到异常的时执行的代码。而try-finally只允许检测异常并做一些必要的清除工作(无论发生错误与否),没有任何异常处理设施。正如你想像的,复合语句两者都可以做到。

try-except:

>>> try:
...     f=open('baba','r')
... except IOError,e:
...     print 'could not open file:',e
... 
could not open file: [Errno 2] No such file or directory: 'baba'
>>> 

3. 核心笔记:忽略代码,继续执行,和向上移交

      try语句块中异常发生点后的剩余语句永远不会到达(所以也永远不会执行)。一旦一个异常被引发,就必须决定控制流下一步到达的位置。剩余代码将被忽略,解释器将搜索处理器,一旦找到,就开始执行处理器中的代码。

      如果没有找到合适的处理器, 那么异常就向上移交给调用者去处理, 这意味着堆栈框架立即回到之前的那个. 如果在上层调用者也没找到对应处理器, 该异常会继续被向上移交, 直到找到合适处理器. 如果到达最顶层仍然没有找到对应处理器, 那么就认为这个异常是未处理的, Python 解释器会显示出跟踪返回消息, 然后退出.


4. (1) 带有多个except的try语句:

def safe_float(obj):
    try:
        retval=float(obj)
    except ValueError:
        retval='could not convert non-number to float'
    except TypeError:
        retval="object type cannot be converted to float"
    return retval

(2) 处理多个异常的except:

except (Exc1[, Exc2[, ... ExcN]])[, reason]:
      suite_for_exceptions_Exc1_to_ExcN

def safe_float(obj):
    try:
        retval=float(obj)
    except (ValueError,TypeError):
        retval='argument must be a number or numeric string'
    return retval

(3) 捕获所有异常

自版本 1.5 后, 异常成为类, 实现这个功能的代码有了很大的改进. 也因为这点(异常成为类),我们现在有一个异常继承结构可以遵循.如果查询异常继承的树结构, 我们会发现 Exception 是在最顶层的, 所以我们的代码可能看起来会是这样:

def safe_float(obj):
    try:
        retval=float(obj)
    except Exception: 
        retval='argument must be a number or numeric string'
    return retval
print safe_float('fdsad')

5. 核心风格: 不要处理并忽略所有错误
       Python 提供给程序员的 try-except 语句是为了更好地跟踪潜在的错误并在代码里准备好处理异常的逻辑. 这样的机制在其他语言(例如 C ) 是很难实现的. 它的目的是减少程序出错的次数并在出错后仍能保证程序正常执行. 作为一种工具而言, 只有正确得当地使用它, 才能使其发挥作用.一个不正确的使用方法就是把它作为一个大绷带"绑定"到一大片代码上. 也就是说把一大段程序(如果还不是整个程序源代码的话)放入一个 try 块中, 再用一个通用的 except 语句 "过滤"掉任何致命的错误, 忽略它们.
# this is really bad code
try:
large_block_of_code # bandage of large piece of code
except Exception: # same as except:
pass # blind eye ignoring all errors
很明显, 错误无法避免, try-except 的作用是提供一个可以提示错误或处理错误的机制, 而不是一个错误过滤器. 上边这样的结构会忽略许多错误, 这样的用法是缺乏工程实践的表现, 我们不赞同这样做.

       底线: 避免把大片的代码装入 try-except 中然后使用 pass 忽略掉错误. 你可以捕获特定的异常并忽略它们, 或是捕获所有异常并采取特定的动作. 不要捕获所有异常,然后忽略掉它们.

6. 异常参数

异常也可以有参数, 异常引发后它会被传递给异常处理器. 当异常被引发后参数是作为附加帮助信息传递给异常处理器的. 虽然异常原因是可选的, 但标准内建异常提供至少一个参数, 指示异常原因的一个字符串.

def safe_float(obj):
    try:
        retval=float(obj)
    except (ValueError,TypeError),diag: 
        retval=str(diag)
    return retval
print safe_float('fdsad')

7. else语句

      我们已经看过else 语句段配合其他的Python 语句,比如条件和循环.至于try-except 语句段,它的功能和你所见过的其他else 没有太多的不同:在try 范围中没有异常被检测到时,执行else 子句.
      在else 范围中的任何代码运行前,try 范围中的所有代码必须完全成功(也就是,结束前没有引发异常).

8. python内建异常

异常名称描述
BaseExceptiona所有异常的基类
SystemExitbpython解释器请求退出
KeyboardInterruptc用户中断执行(通常是输入ctr+c)
Exceptiond常规错误的基类
StopIteratione迭代器没有更多的值
GeneratorExita生成器(generator)发生异常来通知退出
StandardError所有的内建标准异常的基类
ArithmeticErrord所有数值计算错误的基类
FloatingPointErrord浮点计算错误
OverflowError数值运算超出最大限制
ZeroDivisionError除(或取模)零(所有数据类型)
AssertionErrord断言语句失败
AttributeError对象没有这个属性
EOFError没有内建输入,到达EOF标记
EnvironmentErrord操作系统错误的基类
IOError输入/输出操作失败
OSErrord操作系统错误
WindowsErrordwindows系统调用失败
ImportError导入模块/对象失败
LookupErrord无效数据查询的基类
IndexError序列中没有此索引(index)
KeyError映射中没有这个键
MemoryError内存溢出错误(对于Python解释器不是致命的)
NameError未声明/初始化对象(没有属性)
UnboundLocalErrorh访问未初始化的本地变量
ReferenceErrore弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError一般运行时错误
NotImplementedErrord尚未实现的方法
SyntaxErrorPython语法错误
IndentationError缩进错误
TabErrorTab和空格混用
SystemError一般的解释器系统错误
TypeError对类型无效的操作
ValueError传入无效的参数
UnicodeErrorhUnicode相关的错误
UnicodeDecodeErroriUnicode解码时的错误
UnicodeEncodeErroriUnicode编码时的错误
UnicodeTranslateErrorfUnicode转换时的错误
Warningj警告的基类
DeprecationWarningj关于被弃用的特征的警告
FutureWarningi关于构造将来语义会有改变的警告
OverflowWarningk旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarningi关于特性将会被废弃的警告
RuntimeWarningj可疑的运行时行为(runtime behavior)的警告
SyntaxWarningj可疑的语法的警告
UserWarningj用户代码生成的警告


a. Python2.5 新增
b. 在Python2.5 前,Exception 的子类SystemExit
c.在Python2.5 前,StandardError 的子类KeyboardInterrupt
d.Python1.5 新增,用基于类的异常来替代字符串
e.Python2.2 新增
f.Python1.6 新增
g.Python2.0 新增
h.Python1.6 新增
i.Python2.3 新增
j.Python2.1 新增
k.Python2.2 新增,但在Python2.4 时移除


9. 异常与sys模块

另一种获取异常信息的途径是通过sys 模块中exc_info()函数. 此功能提供了一个3 元组(3-tuple)的信息, 多于我们单纯用异常参数所能获得. 让我们看看如何用sys.exc_info() :

>>> try:
...     float('abc123')
... except:
...     import sys
...     exc_tuple=sys.exc_info()
... 
>>> 
>>> print exc_tuple
(<type 'exceptions.ValueError'>, ValueError('could not convert string to float: abc123',), <traceback object at 0x7f3446006878>)

>>> for eachItem in exc_tuple:
...     print eachItem
... 
<type 'exceptions.ValueError'>
could not convert string to float: abc123
<traceback object at 0x7f3446006878>
>>> 
我们从sys.exc_info()得到的元组中是:
  • exc_type: 异常类
  • exc_value: 异常类的实例
  • exc_traceback: 追踪(traceback)对象
       我们所熟悉的前两项:实际的异常类, 和这个异常类的实例(和在上一节我们讨论的异常参数是一样的) . 第三项, 是一个新增的追踪(traceback)对象. 这一对象提供了的发生异常的上下文.它包含诸如代码的执行帧,异常发生时的行号等信息.
       在旧版本中的Python 中, 这三个值分别存在于sys 模块, 为sys.exc_type , sys.exc_value ,sys.exc_traceback . 不幸的是, 这三者是全局变量而不是线程安全的. 我们建议亡羊补牢, 用sys.exc_info()来代替. 在未来版本Python 中,所有这三个变量都将被逐步停用,并最终移除.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值