我的编程空间,编程开发者的网络收藏夹
学习永远不晚

#7 Python代码调试

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

#7 Python代码调试

前言

Python已经学了这么久了,你现在已经长大了,该学会自己调试代码了!相信大家在编写程序过程中会遇到大量的错误信息,我也不例外的啦~遇到这些问题该怎么解决呢?使用最多的方法就是使用print打印中间变量了哇,关于这种方法怎么说呢~low!!!这一节将记录Python中一项很重要的技能:Debug(代码调试),Here We Go!

一、代码调试概述

1.1 概述

一个程序员在编写项目的时候,敲代码其实并不会占用太多的时间,占用时间的其实是敲代码之前(整个项目的思路和框架)和敲代码之后(调试代码)。调试代码这个过程是最让人烦心的事情了,真的是烦到脱发~于是有一项过硬的Debug技巧将会减缓掉头发的速度。Debug的方法有很多,最常用的就是:打印中间变量(print)、使用日志模块(logging)、使用代码调试模块(pdb或ipdb)。接下来将会一一讲解

二、Debug方法一:print函数

2.1 print方法适用情景

在程序报错或者结果与预期不符合时,在源代码中直接使用print函数打印中间变量进行检查。

2.2 print方法例子

 1 '''
 2 从下列段落中提取出所有数字,并输出
 3 本例结果应该是:49737
 4 '''
 5 import re
 6 
 7 
 8 test = ''' JAKARTA, Indonesia—Flag carrier Garuda Indonesia said it is seeking to cancel an order for 49 Boeing Co. 737 MAX jets, saying passengers have lost confidence in the aircraft following two deadly crashes in recent months.  '''
 9 
10 pattern = re.compile('\d')
11 
12 result = re.findall(pattern, test)
13 
14 print(result[0] + result[1])
15 
16 # 运行结果:
17 49

题目要求输出49737,但是自己的程序却只输出了49,这是怎么回事呢?

那就使用print打印一下result这个变量的内容哇,于是,在第13行代码中加入 print(result) :

 1 '''
 2 从下列段落中提取出所有数字,并输出
 3 本例结果应该是:49737
 4 '''
 5 import re
 6 
 7 
 8 test = ''' JAKARTA, Indonesia—Flag carrier Garuda Indonesia said it is seeking to cancel an order for 49 Boeing Co. 737 MAX jets, saying passengers have lost confidence in the aircraft following two deadly crashes in recent months.  '''
 9 
10 pattern = re.compile('\d')
11 
12 result = re.findall(pattern, test)
13 print(result)
14 
15 print(result[0] + result[1])
# 运行结果:
['4', '9', '7', '3', '7']
49

这时就会发现原来是result变量有误,预期result效果为['49', '737']

于是回过头去检查pattern,发现是pattern的锅,应将pattern改为:

pattern = re.compile('\d+')

于是整个程序变为:

 3 '''
 4 从下列段落中提取出所有数字,并输出
 5 本例结果应该是:49737
 6 '''
 7 import re
 8 
 9 
10 test = ''' JAKARTA, Indonesia—Flag carrier Garuda Indonesia said it is seeking to cancel an order for 49 Boeing Co. 737 MAX jets, saying passengers have lost confidence in the aircraft following two deadly crashes in recent months.  '''
11 
12 # pattern = re.compile('\d')
13 pattern = re.compile('\d+')
14 
15 result = re.findall(pattern, test)
16 print(result)
17 
18 print(result[0] + result[1])
# 运行结果:
['49', '737']
49737

结果与预期一样,最后再将 print(result) 这一行删除,整个程序就完工了。

『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep』

2.3 print方法优缺点

优点:

  • 理解和操作方便简单,上手难度低
  • 在编写程序中可以一步一步检查中间变量是否符合预期

缺点:

  • 直接入侵源代码,如果操作失误可能会造成不可挽救的后果
  • 调试完成后需要将这些print行删除掉或者注释掉,否则会造成整个程序运行结果复杂,同时太多print函数的出现会严重拖慢运行速度

三、Debug方法二:logging模块

3.1 日志概述

日志是个什么鬼呢?感觉好像日记的样子哎~日志其实和日记是有很大差别的,日志是用来追踪程序运行过程中发生的事情,将这些事情按照一定的格式写入特定的文件中,以后可以通过分析日志,让管理者更加方便地了解整个程序的的运行情况,尤其是了解到程序的健康状态(优秀的日志分析者甚至可以通过日志分析出开发者的操作习惯和兴趣爱好),最后根据这些结果为程序打上合适的补丁。

3.2 日志作用

  • 代码调试
  • 记录程序的运行状况
  • 为程序打补丁提供支撑

3.3 日志等级

在讲Python日志方法之前,先来了解一下日志中最重要的等级制度:

通常日志分为5个等级:DEBUG, INFO, WARNING, ERROR, CRITICAL

日常编程过程中应该见过WARNING和ERROR吧,一个是警告,一个是错误

从这些单词的英文释义就可以知道每个等级的权重了,DEBUG等级最小,CRITICAL等级最大

还有更详细的等级分法:DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY

3.4 logging模块简介

Python中用来记录日志的模块为:logging,这是一个内置标准库

logging模块的日志等级有5个:DEBUG, INFO, WARNING, ERROR, CRITICAL,另外,logging模块支持用户自定义其他等级,但这并不推荐,因为自定义的等级通常会造成等级混乱,极其容易和他人开发的程序冲突。

日志等级                                等级说明
DEBUG                       详细信息,通常仅在诊断问题时才有意义
INFO                        详细程度仅次于DEBUG,确认事情按预期工作。
WARNING                     表示发生了意外情况,或表明在不久的将来出现了一些问题,但该软件仍在按预期工作。
ERROR                       由于更严重的问题,该软件无法执行某些功能。
CRITICAL                    严重错误,表明程序本身可能无法继续运行。

3.5 logging模块使用方法

3.5.1 日志基本使用方法

1 import logging
2 
3 logging.debug('My level is debug')
4 logging.info('My level is info')
5 logging.warning('My level is warning')
6 logging.error('My level is error')
7 logging.critical('My level is critical')

上述代码就是5种不同级别日志的使用方法,运行一下看看结果如何:

# 运行结果
WARNING:root:My level is warning
ERROR:root:My level is error
CRITICAL:root:My level is critical

这时一定在疑惑,明明是五个等级啊,怎么只输出了后三个等级的内容

logging模块虽然有5的等级,但是他的默认最小等级是WARNING,也就是说,logging模块会自动忽略WARNING以下的等级,那怎么才能输出5个等级的内容呢?

需要在所有输出语句之前配置日志,看例:

1 import logging
2 
3 logging.basicConfig(level=logging.DEBUG)   # 配置日志
4 
5 logging.debug('My level is debug')
6 logging.info('My level is info')
7 logging.warning('My level is warning')
8 logging.error('My level is error')
9 logging.critical('My level is critical')
# 运行结果:
DEBUG:root:My level is debug
INFO:root:My level is info
WARNING:root:My level is warning
ERROR:root:My level is error
CRITICAL:root:My level is critical

那么问题来了, logging.basicConfig 是个什么鬼呢?这个其实就是日志的配置函数,可以配置日志等级、日志输出文件、日志文件的打开模式(默认是追加)、日志格式、日期格式等,这些选项对应的参数分别为:level、filename 、filemode、format、datefmt,举个例子:

1 import logging
2 
3 logging.basicConfig(level=logging.DEBUG, filename='test.log')
4 
5 logging.debug('My level is debug')
6 logging.warning('My level is warning')
7 logging.error('My level is error')

运行之后会发现屏幕并没有日志信息,而是在当前目录下生成一个文件名为‘test.log’的日志文件,打开看一下这个文件:

DEBUG:root:My level is debug
WARNING:root:My level is warning
ERROR:root:My level is error

可以看到已经将日志写入到指定文件了,这样就可以将日志保存下来供以后分析利用了。

有的小伙伴会说,自己能不能修改日志的输出格式呢?比如想要加入时间,完全没有问题,这就要使用format参数了,关于format参数的使用,在下面罗列了一张表格供大家参考:

 1 使用格式                             概述
 2 %(asctime)s                    日志发生时间
 3 %(created)f                    日志发生时间戳
 4 %(relativeCreated)d            日志发生时间相对于logging模块加载时间的相对毫秒
 5 %(msecs)d                      日志发生时间的毫秒部分
 6 %(levelname)s                  日志发生的文字等级(debug、info、warning、error、critical)
 7 %(levelno)s                    日志发生的数字等级(10、20、30、40、50)
 8 %(name)s                       日志记录器名称(默认是root)
 9 %(message)s                    日志文本内容
10 %(pathname)s                   调用日志的源代码的绝对路径
11 %(filename)s                   pathname的文件名部分,包括后缀名
12 %(module)s                     filename的文件名部分,不包含后缀名
13 %(lineno)d                     调用日志的源代码的行数
14 %(funcName)s                   调用日志的函数名
15 %(process)d                    进程号
16 %(prscessName)s                进程名
17 %(thread)d                     线程号
18 %(thread)s                     线程名

举个例子: 

1 import logging
2 
3 LOG_FORMAT = '%(asctime)s - %(levelname)s - %(name)s - %(message)s'
4 logging.basicConfig(level=logging.DEBUG, filename='test.log', format = LOG_FORMAT)
5 
6 logging.debug('My level is debug')
7 logging.warning('My level is warning')
8 logging.error('My level is error')

查看‘test.log’:

DEBUG:root:My level is debug
WARNING:root:My level is warning
ERROR:root:My level is error
2019-03-24 10:52:46,093 - DEBUG - root - My level is debug
2019-03-24 10:52:46,094 - WARNING - root - My level is warning
2019-03-24 10:52:46,094 - ERROR - root - My level is error

可以看到日志输出格式明显发生了改变

注意:打开文件模式默认为追加

如果想要改变时间的输出格式,需要使用datefmt参数,要注意datefmt参数要在format参数里有时间的前提下才会生效,这里就不在举例了,关于时间的格式可以参考time模块时的讲解

3.5.2 日志高级使用方法

以后再介绍哇,基本的使用方法已经可以满足使用了,高级使用方法比较复杂,以后再更新

四、Debug方法三:pdb模块和ipdb模块

4.1 pdb和ipdb概述

pdb是Python内置的Debug模块,但是其功能不够强大,于是便有了第三方模块ipdb的出现;它们两个的关系就好像python和ipython的关系。

ipdb调试代码是比print函数更加高级和灵活的方式,应当熟练应用ipdb的使用方式,并且取代print这种low方法??

ipdb不需要入侵源代码,可以按步执行,可以打断点,可以在程序运行时查看变量值,可以在程序运行时修改变量值,盘它!

4.2 ipdb安装

pip install ipdb

『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep』

4.3 ipdb的使用

学习ipdb,心中要有一张表:

命令                       说明
next或n                   执行下一行
exit或q                   终止程序并退出
p或pp                     打印变量
!                         修改变量
list或l                   查看当前程序代码
break或b                  设置断点
continue或c               继续执行程序直到遇到断点
step或s                   进入函数
return或r                 在函数中使用,执行代码直到遇到断点或者函数结束
help                      帮助

使用ipdb时,可以在代码内部提前导入ipdb模块,但这通常是不现实的;通常采取的方法是这样的,在命令行输入:

python -m ipdb xxx.py

输入以上命令后,便会进入ipdb的debug交互模式,接下来开始举例(多图警告): 

案例代码:

 1 # This is a test for ipdb
 2 # Author: MinuteSheep<minutesheep@163.com>
 3 
 4 import time
 5 import math
 6 
 7 
 8 def get_p_time():
 9     present_time = time.asctime()
10     return present_time
11 
12 
13 a = 123
14 b = 456
15 
16 c = a + b
17 
18 print(c)
19 
20 present_time = get_p_time()
21 
22 print(present_time)

案例1: 使用n

在命令输入 python -m ipdb 4.py 后,会出现如下交互模式: 

聪明的你已经发现代码一进入就执行到了第4行,其实这也很好理解,前面3行都是注释嘛,对代码的执行并没有实际作用,ipdb遇到注释语句会自动跳过的

接下来输入一个n,让那个代码继续执行一行: 

可以看到返回的结果在动态的运行,多输入几次看看效果哇: 

执行多次n后,程序按照预计的顺序执行

注意:执行到18行遇到print(c),但是并没有立即返回结果,那是因为箭头位置是指将要执行这一行了,本次并不会执行,所有下一步才输出c的值579

注意:程序执行到第8行代码时,遇到定义函数,这时在执行下一行时,代码会跳过函数部分,直接来到13行

案例2: 使用exit或q

输入exit或q便会直接退出?

案例3: p或pp

上面图片中可以看到使用p或pp打印变量的值

『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep』

案例4: 使用! 

由上图可知:想要修改变量需要在变量前面加一个!

案例5: 使用list或l 

当你调试代码过程中忘记了程序执行到哪里了的时候,可以使用l来查看一下,效果如上图

案例6: 使用step或s

当遇到执行函数时,默认会在后台执行完函数并且指向下一行代码,但是按照我们的思维,当遇到执行函数时,需要返回头去看看函数时怎么运行的,想要看看代码在函数中时如何一步一步运行的,使用s即可: 

ipdb基本使用方法就这些,还有一点关于断点的使用,下次补充更新?

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

#7 Python代码调试

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

#7 Python代码调试

前言Python已经学了这么久了,你现在已经长大了,该学会自己调试代码了!相信大家在编写程序过程中会遇到大量的错误信息,我也不例外的啦~遇到这些问题该怎么解决呢?使用最多的方法就是使用print打印中间变量了哇,关于这种方法怎么说呢~low
2023-01-31

python调试代码

我在看一些开源的python项目时,需要知道各个类各个函数之间的调用关系才能看懂代码,因此我写了个方法来跟踪代码的调用过程 import sys  from time import ctime  is_log=True  def log_m
2023-01-31

Python代码调试技巧

原文地址:http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/一、使用pdb进行调试pdb是Python自带的包,为Python提供一种交互的源代码调试功能。常用命令
2023-01-31

python调试代码举例

Python自带的pdb库,发现用pdb来调试程序还是很方便的,当然了,什么远程调试,多线程之类,pdb是搞不定的。用pdb调试有多种方式可选:1. 命令行启动目标程序,加上-m参数,这样调用myscript.py的话断点就是程序的执行第一
2023-01-31

如何远程调试Python代码

这是一篇小记。平时使用python写的代码对外部依赖性都不复杂,这些代码在本地调试,运行没问题之后,就可以放到生产去跑了。然而,最近的一个项目,由于使用了一些内部服务,需要连接到内部的环境进行调试。如果每次都修改代码之后,发布一次到内部环境
2023-01-31

Linux下怎么调试python代码

本篇内容介绍了“Linux下怎么调试python代码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Linux下调试pytho代码具体方法日志
2023-06-28

Unity3D代码调试

1.光标定位到代码中的指定行,按F9/单击左键 设置断点。 2.在点击RUN->“Attach to Process...”3.弹出Attach to Process面板出现的面板中选择Process Name为unity Editor(
2023-01-31

python怎么使用pdb调试代码

小编给大家分享一下python怎么使用pdb调试代码,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!使用pdb调试代码Python有自己的内置调试器-pdb。调试器
2023-06-27

vscode如何远程调试python代码

这篇文章主要介绍了vscode如何远程调试python代码的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vscode如何远程调试python代码文章都会有所收获,下面我们一起来看看吧。环境配置配置 python
2023-07-06

Python代码调试的方法是什么

这篇文章主要介绍“Python代码调试的方法是什么”,在日常操作中,相信很多人在Python代码调试的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python代码调试的方法是什么”的疑惑有所帮助!
2023-06-02

Node.js的代码调试debug

在Node.js中调试代码有多种方法,下面列举了一些常用的调试方法:1. 使用console.log():最简单的调试方法是在代码中使用console.log()语句输出变量的值或调试信息。这种方法适用于简单的调试场景,但对于复杂的程序可能
2023-09-17

Python 3 学习笔记:异常代码调试

什么是异常程序运行过程中,产生的错误统称为异常(bug)。这些异常有的可能是语法错误,如关键字输入错误、调用错误等,这一类的异常都是显式的,很好发现;还有一种就是隐式的错误,只用在使用时才会被发现,和使用者的操作有关。下面介绍一下 Pyth
2023-01-31

如何使用pdb进行python代码调试

这篇文章主要讲解了“如何使用pdb进行python代码调试”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用pdb进行python代码调试”吧!pdb为python程序实现了一个交互式调
2023-06-27

pycharm远程调试openstack代码

本文实例为大家分享了pycharm远程调试openstack的具体代码,供大家参考,具体内容如下 1.安装pycharm专业版 本文安装pycharm 2016.2.3专业版。网上教程较多,这里不做详细介绍,只要到pycharm官网上下载应
2022-06-04

如何使用Vim编写和调试Python代码

如何使用Vim编写和调试Python代码要想在Ubuntu下使用VIM编写和调试Python代码,请下安装如下的链接进行配置:https://segmentfault.com/a/1190000003962806 在安装过程中,可以遇到如下
2023-01-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录