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

首先,非常感谢各位打开本博文,本博文是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异常捕获,排错的万能助手
本章节的内容包括:

我们在日常写代码的过程中,经常会遇到各种各样的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技术,感谢你的翻阅,后续有更多好的文章,敬请期待。
不积跬步无以至千里,不积小流无以成江海,感谢各位的支持!

发布了15 篇原创文章 · 获赞 16 · 访问量 438

猜你喜欢

转载自blog.csdn.net/dhjabc_1/article/details/105558404
今日推荐