错误和异常

  • 错误和异常

异常:程序出现了错误而在正常控制流以外采取的行为。

跟踪记录(traceback):包括错误名称、原因和发生错误的行号。

  1. 检查和处理异常:

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

Try另种形式:这两语句是互斥的

try-except:一个try语句中对应一个或多个except

Try-findally:只能有一个finally或是try-except-finally复合语句

语法格式:

Try:

Try_suite #监控这里的异常

Except Exception[,reason]:

Except_suite #异常处理代码

try语句让出错代码不至于影响整个程序的运行,而是之间输出错误原因而继续进下一步操作。注意的点,在try语句中出错代码之后的代码不在运行

 

如果try语句的代码完成后没有异常发生,就会忽略掉except语句继续执行,而如果发生了异常,except语句保存错误的原因,控制流立即跳转到对应的处理器,显示出一个包含错误原因的错误信息,而整个程序不会被中断

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

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

 

如果找不到合适的处理器,异常就一直往上移交给调用者去处理,直到找到合适的处理器,如果到达最顶层都没有找到相应的处理器,那么这个异常就是未处理的,显示出跟踪记录和异常后,程序退出运行

 

  1. 包装和内建函数

>>> float('foo')

Traceback (most recent call last):

  File "<pyshell#7>", line 1, in <module>

    float('foo')

ValueError: could not convert string to float: 'foo'

>>> float([1,2])

Traceback (most recent call last):

  File "<pyshell#8>", line 1, in <module>

    float([1,2])

TypeError: float() argument must be a string or a number, not 'list'

 

Float有两种错误:

  1. 输入类型不正确(只能识别字符串和数字)TypeError
  2. 值不正确(不能转换相应的浮点模式)ValueError

 

想要安全的调用float函数,就要把float函数放到try语句中,使异常发生但是不会终止整个程序

>>> try:

float('foo')

except Exception as e:

print(e)

 

 

could not convert string to float: 'foo'

 

  1. 带有多个excep的try语句

把多个except语句连接在一起,处理一个try块中可能发生的多种异常。

语法格式:

Try:

Try_suite #监控这里的异常

Except Exception[,reason1]:

Except_suite #异常处理代码

Except Exception[,reason2]:

Except_suite #异常处理代码

执行顺序:

先尝试执行try子句:

  1. 如没有异常,忽略所有的except从句继续执行。
  2. 如有异常,解析器将在这个except中找到匹配的异常,如果找到对应的异常处理器,执行流将跳转到这里。

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

 

print(safe_float('xyz'))

print(safe_float(()))

执行结果:

could not convert non-number to float

object type cannot be converted to float

 

  1. 处理多个异常的excep语句

在一个except子句里处理多个异常。Except语句在处理多个异常时要求异常被放在一个元组中:

语法格式:

Try:

Try_suite #监控这里的异常

Except (Exception1,1Exception2) [,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

 

print(safe_float('xyz'))

print(safe_float(()))

执行结果:

argument must be a number or numeric string

argument must be a number or numeric string

 

  1. 捕获所有异常

可以使用exception捕获异常

语法格式:

Try:

Try_suite #监控这里的异常

Except  Exception , e:

#handle real errors

或者:

Try:

Try_suite #监控这里的异常

Except  BaseException , e: #捕获所有异常

#handle all errors

 

 

核心风格:不要处理并忽略所有错误,错误无法避免,try-except的作用是提供一个可以提示错误或处理错误的机制,而不是一个错误过滤器,使用Exception会忽略很多的错误,这样的用法是缺乏工程实践的表现,不赞同这种做法。也不能把大段的代码放到try语句中,只有一小部分可能会引起异常的部分使用try语句,使之不会干扰程序的正常运行

 

  1. “异常参数”

异常也可以有参数,异常引发后它会被传递给异常处理器。参数是作为附加的帮助信息传递给异常处理器的。

 

try:

    float(['fpp'])

except TypeError, diag:

    pass

 

print type(diag)

print diag

<type 'exceptions.TypeError'>

float() argument must be a string or a number

在except中的diag就是异常参数

 

核心风格:遵循异常参数规范

 

如果引发一个ValueError,那么最后提供和解释器引发ValueError时一致的参数信息,可以保证代码的一致性,也能避免其他应用程序在使用这个模块的时候发生错误

  1. 在应用使用我们封装的函数

#coding:utf-8

#定义safe_float函数

def safe_float(obj):

    

    try:

        retval = float(obj)

    except (ValueError, TypeError) :

        retval = 'abcdefg'

    return retval

#定义主函数

def main():

    #打开名为cardlog的文本文件,并传给log

    log = open(r'C:\python\tst\cardlog.txt', 'w')

    #try-except语句验证carddata文件是否存在

    try:

        #打开carddata文本文件,传给ccfile

        ccfile = open(r'C:\python\tst\carddata.txt', 'r')

    except IOError as e:

        log.write('no txns this month\n')

        log.close()

        return

    #将ccfile中的文字读出传给txns

    txns = ccfile.readlines()

    ccfile.close()

    total = 0.00

    log.write('account log:\n')

    #for循环遍历txns

    for eachTxn in txns:

        #将txns中每行文字进行float变换

        result = safe_float(eachTxn)

        #使用isinstance函数判断result里的值是否为浮点数

        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()

信用卡交易系统,用来统计余额

 

  1. else子句

在try范围中没有异常被检测到时,执行else子句。

在else范围中的任何代码运行前,try范围中的所有代码必须完全成功。

  1. Finally

Finally子句是无论异常是否发生,是否捕获都会执行的一段代码

语法格式:

Try:

A

Except MyException:

B

Else:

C

Finally:

D

 

  1. try-finally语句

 

另一种使用finally的方式是finally单独和try连用。try-finally不是用来捕捉异常,作为替代,它常常用来维持一致的行为,而无论异常是否发生。

语法格式:

Try:

Try_suite

Finally:

Finally_suite #无论如何都执行

 

示例:

try:

    #打开carddata文本文件,传给ccfile

    ccfile = open(r'C:\python\tst\carddata.txt', 'r')

except IOError as e:

    log.write('no txns this month\n')

finally:

    ccfile.close()  #无论是否有异常文件都会被关闭

本质:可以同时处理在原始的try语句块和finally语句块中发生的错误。这种方法问题:当finally语句块中地区发生异常时,会对手原来异常的上下文信息,除非在某个地方保存了它。

烦的这种写法的理由:在很多情况下,异常处理器需要做一些扫尾工作,而如果你在异常处理之前,用finally语句块中是否了某些资源,你就不能再去做这些工作了,简单的说:finally语句块并不是如你所想的是“最终的final”

注意点:如果finally中的代码引发了另一个异常或由于return、break、continue语法而终止,原来的异常将丢失而且无法重现引发。

  1. try-except-else-finally

 

无论选择什么语法,至少要有一个except自己,而else和finally都是可选的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值