• 48-调试器(1)


    复习异常:

    try:          #有可能发生异常部分
        print('try...')
        #r = 10 / 2
        r = 10 / 0
        print('result:', r) #如果正常会走到这里
    except ZeroDivisionError as e: #发生除零异常会走到这里 {没有就跳过except}
        print('except:', e)
    finally:                #必定会走finally {当然,这个finally部分可以不写}
        print('finally...')
    print('END
    ')
    
    
    try:
        print('try...')
        #r = 10 / int('0')    #分母为0,ZeroDivisionError
        r = 10 / int('hao') #'hao'无法转化成数字,ValueError
        print('result:', r)
    except ValueError as e:
        print('ValueError:', e)
    except ZeroDivisionError as e:
        print('ZeroDivisionError:', e)
    finally:
        print('finally...')
    print('END
    ')
    
    
    try:
        print('try...')
        r = 10 / int('2')
        print('result:', r)
    except ValueError as e:
        print('ValueError:', e)
    except ZeroDivisionError as e:
        print('ZeroDivisionError:', e)
    else: #当所有except都没有执行就执行else,当然这个else也是可省略的
        print('no error!')
    finally:
        print('finally...')
    print('END
    ')
    
    
    #所有的错误类型都继承自BaseException,except会把当前xxxError以及这个xxxError的子类都捕获到,
    #故而设计except的时候要注意这一点,不要设计冗余无用的except分支
    try:
        r = 10 / int('abc')
    except ValueError as e:
        print('ValueError')
    except UnicodeError as e: #UnicodeError是ValueError的子类,所以ValueError会把
        print('UnicodeError') #UnicodeError冲掉,UnicodeError这个分支永远不会执行,故可以删去
    #详细继承关系,
    #见官网:https://docs.python.org/3/library/exceptions.html#exception-hierarchy
    
    
    #由于异常可以穿越多层调用,层层传递,故只需要在合适的层次catch和except即可。
    #比如,foo()出错了,错误被传递至bar,main,只需要在main(),catch和except就可以了。
    '''
    def foo(s):
        return 10 / int(s)
    
    def bar(s):
        return foo(s) * 2
    
    def main():
        try:
            bar('0')
        except Exception as e:
            print('Error:', e)
        finally:
            print('finally...')
    '''
    #错误层层上抛,形成调用栈:
    # def foo(s):
        # return 10 / int(s) #两类错:1.除0;2.非数字串
    
    # def bar(s):
        # return foo(s) * 2
    
    # def main():
        # bar('0')
    # main()
    #main()处首先报错,是由于bar()引发的,而bar()的错又是foo()引发的,根源是foo(),但
    #但是可以在main()处except
    
    
    #logging:既能记录错误栈,也能保证程序继续运行下去
    import logging
    def foo(s):
        return 10 / int(s)
        
    def bar(s):
        return foo(s) * 2
        
    def main():
        try:
            bar('0')
        except Exception as e:
            logging.exception(e) #打印错误栈信息,并且程序能够正确运行至退出
    
    main()
    print('END
    ') #若程序能到这里,说明前面的logging的确能支持 “程序遇到错误后,依旧正常运行”
    
    
    #错误的本质是class,所以捕获错误catch到的就是这个class的一个instance
    #故而我们可以继承已有的xxxError,自定义一个错误的class,并用raise在合适的时机抛出错误
    class FooError(ValueError): #自定义的错误class
        pass
    
    # def foo(s):
        # n = int(s)
        # if n==0:
            # raise FooError('invalid value: %s' % s) #防止程序往下走,因为再往下就要除0了
        # return 10 / n
    
    # foo('0')
    
    
    
    #还有一个错误处理方式:
    # def foo(s):
        # n = int(s)
        # if n==0:
            # raise ValueError('invalid value: %s' % s)
        # return 10 / n
    
    # def bar():
        # try:
            # foo('0')
        # except ValueError as e:
            # print('ValueError!')
            # raise    #把ValueError原封不动地向bar()的上层抛,让调用bar()的上层处理错误
            # # raise ValueError('input error') #把错误稍作处理再往上层抛
    # bar()
    
    
    
    #########################################################################################
    #作业:定位错误
    from functools import reduce
    from decimal import *
    def str2num(s):    #可能s不是‘整数数字串’,引发ValueError
        #return int(s)  #int()要求传入 {整数数字串}
        return Decimal(s) #把数字串转化成10进制的数字
    def calc(exp):
        ss = exp.split('+') #根据+ 把exp分割成一个list
        ns = map(str2num, ss) #把这个list的每个元素由str变成int
        return reduce(lambda acc, x: acc + x, ns) #等价于sum(ns)
    
    def main():
        r = calc('100 + 200 + 345')
        print('100 + 200 + 345 =', r)
        r = calc('99 + 88 + 7.6')
        print('99 + 88 + 7.6 =', r)
    
    main()
  • 相关阅读:
    cf 786B. Legacy(线段树区间建图)
    cf 1416D. Graph and Queries (生成树重构+线段树维护dfs序)
    cf 1437E. Make It Increasing
    cf 1434D. Roads and Ramen (树上最长偶权链)
    cf 1413C (贪心排序+双指针)
    cf 1421E. Swedish Heroes (dp)
    CF1428 F.Fruit Sequences
    11.Redis详解(十一)------ 过期删除策略和内存淘汰策略
    10.Redis详解(十)------ 集群模式详解
    9.Redis详解(九)------ 哨兵(Sentinel)模式详解
  • 原文地址:https://www.cnblogs.com/LS1314/p/8504610.html
Copyright © 2020-2023  润新知