10.2 Python中的异常
1、NameError :尝试访问一个未申明的变量
>>> foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
name 'foo' is not defined
2、ZeroDivisionError: 除数为零
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
integer division or modulo by zero
3、SyntaxError: 语法错误
4、IndexError: 请求的索引超出序列范围
5、KeyError: 请求一个不存在的字典的键
6、IOError: 输入/输出错误
7、AttributeError: 尝试访问未知的对象属性
10.3 检测和处理异常
异常可以通过try语句来检测。
try语句有两种主要形式: try-except 和 try-finally。这两个语句互斥。一个try语句可以对应一个或多个except子句,但只能对应一个finally子句或是一个try-except-finally复合语句。
10.3.1 try-except语句
try:
try_suite
except Exception[, reason]:
except_suite
>>> try:
... f = open('haha', 'r')
... except IOError, e:
... print 'could not open file: ', e
could not open file: [Errno 2] No such file or directory: 'haha'
10.3.2 包装内建函数
>>> def safe_float(obj):
... try:
... retval = float(obj)
... except ValueError:
... retval = 'could not convert non-number to float'
... return retval
>>> safe_float('2134')
2134.0
>>> safe_float('bad input')
'could not convert non-number to float'
>>> safe_float([a, b])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
name 'a' is not defined
>>> safe_float(['a', 1])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in safe_float
TypeError: float() argument must be a string or a number
float() argument must be a string or a number
10.3.3 带有多个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
>>> safe_float(())
'object type cannot be converted to float'
10.3.4 处理多个异常的except语句
>>> def safe_float(obj):
... try:
... retval = float(obj)
... except (ValueError, TypeError):
... retval = 'argument must be a number or numeric string'
... return retval
>>> safe_float(())
'argument must be a number or numeric string'
>>> safe_float('asdf')
'argument must be a number or numeric string'
10.3.5 捕获所有异常
try:
:
except Exception, e:
#error occured, log ‘e’, etc
>>> def safe_float(obj):
... try:
... retval = float(obj)
... except Exception, e:
... print 'some wrong : ', e
>>> safe_float(())
some wrong : float() argument must be a string or a number
>>> safe_float('asd')
some wrong : could not convert string to float: asd
10.3.6 异常参数
异常也可以有参数,异常引发后它会被传递给异常处理器。虽然异常原因是可选的,但是标准内建异常提供至少一个参数,指示异常原因的一个字符串。
异常的参数可以在处理器里忽略,但Python提供了保存这个值的语法。要想访问提供的异常原因,必须保留一个变量来保存这个参数。
>>> def safe_float(obj):
... try:
... retval = float(obj)
... except (ValueError, TypeError), diag:
... retval = str(diag)
... return retval
>>> safe_float(())
'float() argument must be a string or a number'
>>> safe_float('asd')
'could not convert string to float: asd'
10.3.7 在应用使用我们封装的函数
#!/usr/bin/python
# -*- coding:utf-8 -*-
def safe_float(obj):
'safe version of float()'
try:
¦ retval = float(obj)
except (ValueError, TypeError), diag:
¦ retval = str(diag)
return retval
def main():
'handles all the data processing'
log = open('cardlog.txt', 'w')
try:
¦ ccfile = open('carddata.txt', 'r')
except IOError, e:
¦ log.write('no txns this month\n')
¦ log.close()
¦ return
txns = ccfile.readlines()
ccfile.close()
total = 0.00
log.write('account log: \n')
for eachTxn in txns:
¦ result = safe_float(eachTxn)
¦ if isinstance(result, float):
¦ ¦ total += result
¦ ¦ log.write('data......processed\n')
¦ else:
¦ ¦ log.write('ignored: %s' % result)
print '$%.2f (new balance)' % (total)
log.close()
if __name__ == '__main__':
main()
10.3.8 else子句
在try范围内没有异常被检测到,执行else子句。
10.3.9 finally子句
无论异常是否发生,是否捕获都会执行finally子句。
10.3.10 try-finally 语句
1 try:
2 try:
3 ¦ ccfile = open('carddata.txt', 'r')
4 ¦ txns = ccfile.readlines()
5 except IOError:
6 ¦ log.write('no txns this month\n')
7 finally:
8 ccfile.close()
10.4 上下文管理
10.4.1 with语句
with context_expr [as var]:
with_suite
支持上下文管理协议的对象:
file, decimal.Context, thread.LockType, threading.Lock, threading.RLock, threading.Condition, threading.Semaphore, threading.BoundedSemaphore
with open('/etc/passwd', 'r') as f:
for eachLine in f:
expr_suite
>>> with open('/etc/passwdd', 'r') as f:
... for i in f:
... print i,
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: '/etc/passwdd'
[Errno 2] No such file or directory: '/etc/passwdd'
10.4.2 上下文管理协议
10.6 触发异常
raise语句
1、语法与惯用法
raise [Some_Exception [, args [, traceback]]]
第一个参数 SomeException,是触发异常的名字。如果有,必须是一个字符串,类或实例。如果有其他参数,arg或traceback, 就必须提供SomeException。
第二个符号为可选的args,来传给异常。当异常发生时,异常的参数总是作为一个元组传入。
最后一项参数,是当异常触发时新生成一个用于异常-正常化的跟踪记录对象。
10.7 断言
断言是一句必须等价于布尔真的判断;此外,发生异常也意味着表达式为假。
断言语句等价于这样的python表达式,若断言成功,不采取任何措施,否则触发AssertionError 的异常。
assert expression [, arguments]
>>> assert 1 == 1
>>> assert 1 == 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> assert 1 == 0, 'one does not equal zero'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: one does not equal zero
one does not equal zero
>>> try:
... assert 1== 0, 'one does not equal zero'
... except AssertionError, args:
... print '%s: %s' % (args.__class__.__name__, args)
AssertionError: one does not equal zero