您的位置:首页 > 编程语言 > Python开发

Python基础系列(六)Debug代码跟踪和try-except异常捕获,排错的万能助手

2020-06-01 04:35 627 查看

首先,非常感谢各位打开本博文,本博文是Python入门基础系列文章之一,Python目前是非常火的编程工具,其实作为编程不在只是程序员的专利,每一个人在日常的工作中、学习中都会或多或少的要用到一些工具去帮助我们解决问题,那么Python将会是一个非常合适的工具之一。
笔者认为,python已经类似office一样,成为了我们日常办公中的重要工具。
作为Python入门基础系列文章,共包含六篇,具体文章如下:

  1. 好的开始,是成功的起点。(python+pycharm+print+pip+快捷键)
  2. 基础概念,进入python的第一课!(基本类型认知、互转)
  3. 文件操作,让python与外界互联互通!(os)
  4. 多线程处理,python的一把利器!(thread)
  5. 类和对象,让你更懂你的python代码!(class)
  6. Debug代码跟踪和try-except异常捕获,排错的万能助手!(DEBUG)

千里之行,始于足下,让我们一起在python的世界里分享、学习、共同进步吧!
好的,下面让我们正式进入本章:Debug代码跟踪和try-except异常捕获,排错的万能助手
本章节的内容包括:

文章目录

  • 三、Exception(异常)
  • 四、try异常处理
  • 五、常用的异常处理技巧
  • 六、使用pycharm的Debug调试
  • 我们在日常写代码的过程中,经常会遇到各种各样的bug,这些bug有可能是本身对于语法不熟练引起的、也有可能是因为程序运行期抛出异常引起的。那么,有什么办法能够让我们对这些bug有效处理,使我们能驾驭得了我们的python代码?

    一、浅谈bug的分类:

    我们通常将 bug 分为

    Error(错误)
    Exception(异常)

    二、Error(错误)

    错误 通常是指程序中的 语法错误 或 逻辑错误,也许是我们学习Python过程中最常见抱怨。

    (一)语法错误:

    如python需要对代码进行缩进排版:

    def run():
    print('hello','world')
    
    if __name__ == '__main__':
    run()

    提示信息如下:

    File "debug01.py", line 2
    print('hello','world')
    ^
    IndentationError: expected an indented block

    如定义函数或者类需要用

    进行定义和声明:

    def run()
    print('hello','world')
    
    if __name__ == '__main__':
    run()

    提示信息如下:

    File "debug01.py", line 1
    def run()
    ^
    SyntaxError: invalid syntax

    语法分析器指出错误所在的文件名和行号,所以如果是从脚本输入的你就知道去哪里检查错误了。

    (二)逻辑错误:

    如0不能是分母:

    def run():
    k = 2/0
    print(k)
    
    if __name__ == '__main__':
    run()

    提示信息如下:

    Traceback (most recent call last):
    File "debug01.py", line 6, in <module>
    run()
    File "debug01.py", line 2, in run
    k = 2/0
    ZeroDivisionError: division by zero

    如地址越界:

    def run():
    li = [1,2,3]
    print(li[3])
    
    if __name__ == '__main__':
    run()

    提示信息如下:

    Traceback (most recent call last):
    File "debug01.py", line 6, in <module>
    run()
    File "debug01.py", line 3, in run
    print(li[3])
    IndexError: list index out of range

    如无法访问不存在的对象:

    def run():
    li = [1,2,3]
    del li
    print(li)
    
    if __name__ == '__main__':
    run()

    提示信息如下:

    Traceback (most recent call last):
    File "debug01.py", line 7, in <module>
    run()
    File "debug01.py", line 4, in run
    print(li)
    UnboundLocalError: local variable 'li' referenced before assignment

    等等,这些错误都是我们人为产生的,也是我们在日常写代码的过程中需要不断完善和学习提升的。

    这一类的问题更多的是语法层面的问题。更多的是需要提升我们的代码修养。

    三、Exception(异常)

    即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误,运行期检测到的错误被称为异常;

    (1)大多数的异常都不会被程序处理,都以错误信息的形式展现。
    (2)BaseException为所有异常的基类,其下面分为:SystemExit、KeyboardInterrupt、GeneratorExit、Exception四类异常, 我们碰到最多的基本上都是Exception,Exception为所有非系统退出类异常的基类;
    (3)Exception下包含我们常见的多种异常如:MemoryError(内存溢出)、BlockingIOError(IO异常)、SyntaxError(语法错误异常)等。

    如IO异常:(字符编码问题,文件是UTF-8格式,但是我们在打开的时候使用GBK格式打开,抛出异常)

    def run():
    with open('test.txt','r',encoding='gbk') as f:
    str = f.readlines()
    print(str)
    
    if __name__ == '__main__':
    run()

    提示信息如下:

    Traceback (most recent call last):
    File "debug01.py", line 7, in <module>
    run()
    File "debug01.py", line 3, in run
    str = f.readlines()
    UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 34: illegal multibyte sequence

    如pip版本异常:(使用python3.x版本,但是使用python2.x的类库访问)

    import TKinter as tk
    # import tkinter as tk
    root = tk.Tk()
    root.mainloop()

    提示信息如下:

    Traceback (most recent call last):
    File "debug01.py", line 1, in <module>
    import TKinter as tk
    ModuleNotFoundError: No module named 'TKinter'

    针对上面提到的bug,我们可以使用如下两种方法进行处理:

    四、try异常处理

    我们在写程序的时候已经预料到了它可以出现这样的错误,那么我们就可以提前捕获这些错误。

    (一)异常处理流程图

    try 语句的工作方式为:
    (1)首先,执行 try 子句 (在 try 和 except 关键字之间的部分); 如果没有异常发生, except子句 在 try 语句执行完毕后就被忽略了; 如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略; 如果异常匹配于
    (2)except 关键字后面指定的异常类型,就执行对应的except子句,然后继续执行 try 语句之后的代码; 如果发生了一个异常,在 except 子句中没有与之匹配的分支,它就会传递到上一级 try 语句中; 如果最终仍找不到对应的处理语句,它就成为一个未处理异常,终止程序运行,显示提示信息。
    (3)try/except 语句还可以带有一个 else、finally子句,else子句只能出现在所有 except 子句之后,只有在没有出现异常时执行;finally 子句放在最后,无论是否出现异常都会执行。

    (二)常见的异常类

    异常 说明
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    NameError 使用一个还未被赋予对象的变量
    TypeError 传入对象类型与要求的不符合
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的

    (三)处理单个异常

    try:
    code   #处理的语句
    except  Error1 as e:   #遇到Error1执行下面的语句,在python2中写成except  Error1,e
    print(e)

    (四)处理多个异常

    try:
    code
    except Error1 as e:  #处理Error1异常
    print(e)
    except Error2 as e:   #处理Error2异常
    print(e)

    (五)else处理

    **作用:**没有异常,则走else部分的逻辑代码

    try:
    print("qigao,handson")    #代码没有异常
    except (IndexError,KeyError) as e:
    print(e)
    except Exception as e:
    print(e)
    else:             #没有异常出错,走else的逻辑代码
    print("没有异常")

    (六)finnally处理

    作用:不管有没有错误,都会执行finnally中的代码

    try:
    code
    except (Error1,Error2,...) as e:
    print(e)
    except Exception as e:
    print(e)
    else:
    print("没有错误,执行")
    finnally:
    print("不管有没有错,都执行finnally")

    五、常用的异常处理技巧

    (一)捕获所有异常

    try:
    code
    except Exception as e:
    print(e.message)

    (二)采用traceback模块查看异常

    #引入python中的traceback模块,跟踪错误
    import traceback
    try:
    code
    except:
    traceback.print_exc()

    (三)采用sys模块回溯最后的异常

    #引入sys模块
    import sys
    try:
    code
    except:
    info=sys.exc_info()
    print info[0],":",info[1]

    六、使用pycharm的Debug调试

    (一)添加断点:

    直接在标记处点击鼠标左键即可。(删除断点只需再点击断点处即可)

    (二)Debug运行代码

    (三)debug相关功能

    按照所需调试进行代码调试。Debug的调试方式如下所示:

    F8:step over 单步
    遇到断点后,程序停止运行,按F8单步运行。
    F7:step into 进入
    配合F8使用。单步调试F8时,如果某行调用其他模块的函数,在此行F7,可以进入函数内部,如果是F8则不会进入函数内容,直接单步到下一行。
    Alt+shift+F7:step into mycode,
    个人理解F8和F7的综合。1、没遇到函数,和F8一样;2、遇到函数会自动进入函数内部,和F8时按F7类似的
    shift+F8:跳出
    调试过程中,F7进入函数内后,shift+F8跳出函数,会回到进入前调用函数的代码。不是函数地方shift+F8跳出,怎么用没太明白,但最终会执行到结束。
    F9:resume program
    按翻译是重启程序 ,实际是 下个断点,当打多个断点是,F9会到下一个断点。

    好的,至此已经基本上介绍完了python的异常处理和debug技术,感谢你的翻阅,后续有更多好的文章,敬请期待。
    不积跬步无以至千里,不积小流无以成江海,感谢各位的支持!

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: