zoukankan      html  css  js  c++  java
  • Python学习笔记九 错误、调试

    参考教程:廖雪峰官网https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

    一、错误处理

    Python提供了一套try...except...finally...的错误处理机制,先看一个示例:

    try:
        print("try...")
        r=10/0
        print("result:",r)
    except ZeroDivisionError as e:
        print("except:",e)
    finally:
        print("finally...")
    print('END')

    执行结果如下:

    try...
    except: division by zero
    finally...
    END

    try语句后面跟的是我们认为可能出错的代码,如果真的出错了就会停止执行其中的代码并转向except语句;无论是否出错最后都会执行finally语句的代码。

    这里因为出错的是除数是0这个错误,所以在except中直接写定了该中错误的类型“ZeroDivisionError”;但有时候我们不明确到底会错误类型,所以可以通过多个except去处理:

    try:
        print("try...")
        r=10/int('a')
        print("result:",r)
    except ValueError as e:  #处理值类型错误
        print("ValueError:",e)
    except ZeroDivisionError as e:#处理除数为0错误
        print("except:",e)
    finally:
        print("finally...")
    print('END')

    如果没有错误发生,我们也可以在try...except...后面跟一个else语句,这里的代码可以在没有错误发生时运行。

    try:
        print("try...")
        r=10/int('11')
        print("result:",r)
    except ValueError as e:  #处理值类型错误
        print("ValueError:",e)
    except ZeroDivisionError as e:#处理除数为0错误
        print("except:",e)
    else:
        print('no error!')
    finally:
        print("finally...")
    print('END')

    使用try...except语句还有一个好处,就是跨越多层调用,假设有三个函数: foo() bar() main(),依此为调用关系,如果foo()运行时候出错了,我们在调用环节就可以对其进行处理。

    def foo(s):
        return 10/int(s)
    
    def bar(s):
        return foo(s)*2
    
    def main():
        try:
            bar('0')
        except Exception as e:
            print("Exception:",e)
        finally:
            print('finally')
    
    main()
    
    #输出:
    Exception: division by zero
    finally

    可以看出,我们不需要在每个可能出错的地方去捕获并处理错误,在合适的层次去处理就可以了。

     *调用栈

    如果错误没有被捕获,就会一直往上一层抛出,如果一直没有被捕获处理,最后将被解释器捕获,并打印一个错误信息。

    def foo(s):
        return 10/int(s)
    
    def bar(s):
        return foo(s)*2
    
    def main():
        bar('0')
        
    main()

    执行结果如下:

    Traceback (most recent call last):  #错误追朔
      File "...", line 10, in <module>  #首先出错的是第10行的main()
        main()
      File "...", line 8, in main       #但上面出错的原因在第8行bar('0')
        bar('0')
      File "...", line 5, in bar        #但上面出错的原因在第5行return foo(s)*2
        return foo(s)*2
      File "...", line 2, in foo        #但上面出错的原因在第2行 return 10/int(s)
    return 10/int(s)
    ZeroDivisionError: division by zero  #这里已经不再追朔,而是已经找到错误源头,直接给出错误类型,是一个除数为0错误

    上面的代码在出错后已经停止运行了,并且给出了追朔过程及错误信息。既然Python的traceback可以追朔出错原因,那它也提供了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!")

    二、调试

    (一)断言(assert)

    对于可能出错的地方都可以插入assert语句分析测试:

    def foo(s):
        n=int(s)
        assert n!=0,'n is zero!'
        return 10/n
    
    def main():
        foo('0')
    
    main()

    上述代码中增加了“assert n!=0,'n is zero!'”,表示:断言n必须不为0,否则报错信息。断言失败则会抛出AssertError:

    Traceback (most recent call last):
    。。。
    AssertionError: n is zero!

    (二)logging

    和assert相比,logging不会抛出错误,而且可以输出错误信息到文本

    import logging
    logging.basicConfig(level=logging.INFO)
    
    s='0'
    n=int(s)
    logging.info('n=%d',n)   #logging的用法同样是放到可能出错的代码处
    print(10/n)
  • 相关阅读:
    Linux系列教程(二十)——Linux的shell概述以及如何执行脚本
    Linux系列教程(十九)——Linux文件系统管理之手工分区
    Linux系列教程(十八)——Linux文件系统管理之文件系统常用命令
    Linux系列教程(十七)——Linux权限管理之文件系统系统属性chattr权限和sudo命令
    Linux系列教程(十六)——Linux权限管理之ACL权限
    Linux系列教程(十五)——Linux用户和用户组管理之用户管理命令
    flask-sqlalchemy用法详解
    flask 扩展包
    机器学习的数学基础-(三、概率论和数理统计)
    机器学习的数学基础-(二、线性代数)
  • 原文地址:https://www.cnblogs.com/tsembrace/p/8697270.html
Copyright © 2011-2022 走看看