Python核心编程----错误和异常

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




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值