概述
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 | 所有异常的基类 |
SystemExitb | python解释器请求退出 |
KeyboardInterruptc | 用户中断执行(通常是输入ctr+c) |
Exceptiond | 常规错误的基类 |
StopIteratione | 迭代器没有更多的值 |
GeneratorExita | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticErrord | 所有数值计算错误的基类 |
FloatingPointErrord | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零(所有数据类型) |
AssertionErrord | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF标记 |
EnvironmentErrord | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSErrord | 操作系统错误 |
WindowsErrord | windows系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupErrord | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python解释器不是致命的) |
NameError | 未声明/初始化对象(没有属性) |
UnboundLocalErrorh | 访问未初始化的本地变量 |
ReferenceErrore | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般运行时错误 |
NotImplementedErrord | 尚未实现的方法 |
SyntaxError | Python语法错误 |
IndentationError | 缩进错误 |
TabError | Tab和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeErrorh | Unicode相关的错误 |
UnicodeDecodeErrori | Unicode解码时的错误 |
UnicodeEncodeErrori | Unicode编码时的错误 |
UnicodeTranslateErrorf | Unicode转换时的错误 |
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)对象
在旧版本中的Python 中, 这三个值分别存在于sys 模块, 为sys.exc_type , sys.exc_value ,sys.exc_traceback . 不幸的是, 这三者是全局变量而不是线程安全的. 我们建议亡羊补牢, 用sys.exc_info()来代替. 在未来版本Python 中,所有这三个变量都将被逐步停用,并最终移除.
最后
以上就是自由玫瑰为你收集整理的python错误和异常的全部内容,希望文章能够帮你解决python错误和异常所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复