#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方法例子
'''
从下列段落中提取出所有数字,并输出
本例结果应该是:49737
'''
import re 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. ''' pattern = re.compile('\d') result = re.findall(pattern, test) print(result[0] + result[1]) # 运行结果:
49
题目要求输出49737,但是自己的程序却只输出了49,这是怎么回事呢?
那就使用print打印一下result这个变量的内容哇,于是,在第13行代码中加入 print(result) :
'''
从下列段落中提取出所有数字,并输出
本例结果应该是:49737
'''
import re 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. ''' pattern = re.compile('\d') result = re.findall(pattern, test)
print(result) print(result[0] + result[1])
# 运行结果:
['', '', '', '', '']
49
这时就会发现原来是result变量有误,预期result效果为['49', '737']
于是回过头去检查pattern,发现是pattern的锅,应将pattern改为:
pattern = re.compile('\d+')
于是整个程序变为:
'''
从下列段落中提取出所有数字,并输出
本例结果应该是:49737
'''
import re 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. ''' # pattern = re.compile('\d')
pattern = re.compile('\d+') result = re.findall(pattern, test)
print(result) print(result[0] + result[1])
# 运行结果:
['', '']
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 日志基本使用方法
import logging
logging.debug('My level is debug')
logging.info('My level is info')
logging.warning('My level is warning')
logging.error('My level is error')
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个等级的内容呢?
需要在所有输出语句之前配置日志,看例:
import logging
logging.basicConfig(level=logging.DEBUG) # 配置日志
logging.debug('My level is debug')
logging.info('My level is info')
logging.warning('My level is warning')
logging.error('My level is error')
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,举个例子:
import logging
logging.basicConfig(level=logging.DEBUG, filename='test.log')
logging.debug('My level is debug')
logging.warning('My level is warning')
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参数的使用,在下面罗列了一张表格供大家参考:
使用格式 概述
%(asctime)s 日志发生时间
%(created)f 日志发生时间戳
%(relativeCreated)d 日志发生时间相对于logging模块加载时间的相对毫秒
%(msecs)d 日志发生时间的毫秒部分
%(levelname)s 日志发生的文字等级(debug、info、warning、error、critical)
%(levelno)s 日志发生的数字等级(10、20、30、40、50)
%(name)s 日志记录器名称(默认是root)
%(message)s 日志文本内容
%(pathname)s 调用日志的源代码的绝对路径
%(filename)s pathname的文件名部分,包括后缀名
%(module)s filename的文件名部分,不包含后缀名
%(lineno)d 调用日志的源代码的行数
%(funcName)s 调用日志的函数名
%(process)d 进程号
%(prscessName)s 进程名
%(thread)d 线程号
%(thread)s 线程名
举个例子:
import logging LOG_FORMAT = '%(asctime)s - %(levelname)s - %(name)s - %(message)s'
logging.basicConfig(level=logging.DEBUG, filename='test.log', format = LOG_FORMAT) logging.debug('My level is debug')
logging.warning('My level is warning')
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方法
#7 Python代码调试的更多相关文章
- 【转载】Python 代码调试技巧
https://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/ Python 代码调试技巧 张 颖2012 年 5 月 03 日发布 ...
- Python开发环境Wing IDE的Blender的Python代码调试技巧
Wing IDE是一个集成开发环境,可用于开发.测试和调试为Blender编写的Python代码,Blender是一个开源的3 D内容创建系统.Wing IDE提供自动完成.调用提示.强大的调试器.以 ...
- python - 代码调试的好帮手sys._getframe()
python 的调试,令人非常忧伤,通过将输出路径打印的方式,可以提高很大的方便性: import sys #coding=utf-8 def get_cur_info(): print sys._g ...
- 【转】Python 代码调试技巧
转载自:http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/ Debug 对于任何开发人员都是一项非常重要的技能,它能够帮助我 ...
- Python 代码调试技巧
使用 pdb 进行调试 pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点.单步调试.进入函数调试.查看当前代码.查看栈片段.动态改变变 ...
- Python - 调试Python代码的方法
调试(debug) 将可疑环节的变量逐步打印出来,从而检查哪里是否有错. 让程序一部分一部分地运行起来.从核心功能开始,写一点,运行一点,再修改一点. 利用工具,例如一些IDE中的调试功能,提高调试效 ...
- 使用pycharm远程调试python代码
使用 pycharm 进行 python 代码远程调试 pycharm 的远程调试是从远程机器连接到本地机器,需要在远程机器的py文件中指定本地机器的IP和端口. 远程机器上,通过easy_insta ...
- [置顶] 如何在Python IDLE中调试Python代码?
好久没有用Python了,居然忘记了怎么在Python IDLE中调试Python代码.百度了一下,然后还是写下来吧,以免以后又忘记了. 1. Set break point in the sourc ...
- 用VScode代码调试Python
Python扩展支持许多类型的Python应用程序的调试,包括以下一般功能: 观看窗口 评估表达式 当地人 参数 扩大孩子 断点 条件断点 暂停(进入)正在运行的程序 自定义启动目录 要熟悉这些常规功 ...
随机推荐
- 基础java中的package的命名规则和import的使用
包的命名一般用公司域名但是注意域名后辍要放前面如下 package com.cnblogs.i.Cat//对应地址是com/cnblos/i/cat.class也就是Cat.class的地址 如果想将 ...
- 我在B站投稿啦、、、
我在B站投稿啦....欢迎评论交流... https://www.bilibili.com/video/av31539882/ 怎样激活Win10系统修改windows系统账户的名称-mp4 外链: ...
- android中进度条的实现
布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:androi ...
- kvm虚拟机克隆
1.先关闭被克隆的虚拟机: 2.克隆命令 virt-clone -o 192.168.0.242_sw_web -n 192.168.0.163_nginx -f /data/kvm/images/1 ...
- python从入门到实践-10章文件和异常(括号问题)
#!/user/bin/env python# -*- coding:utf-8 -*- # 1.从文件中读取数据with open('pi_digits.txt') as file_object: ...
- node koa2 玩起来都是中间件啊
玩的我想吐 !!! 整理下常用的中间件吧! 先列在这有空把这些中间件的使用技巧也写出来分享一下koa-router 路由中间件koa-bodyparser POST数据处理的中间件koa-stri ...
- 串口RS232和485通信的波形分析
一.串行数据的格式 异步串行数据的一般格式是:起始位+数据位+停止位,其中起始位1 位,数据位可以是5.6.7.8位,停止位可以是1.1.5.2位. 起始位是一个值为0的位,所以对于正逻辑的TTL电平 ...
- 最小生成树 kruskal算法&prim算法
(先更新到这,后面有时间再补,嘤嘤嘤) 今天给大家简单的讲一下最小生成树的问题吧!(ps:本人目前还比较菜,所以最小生成树最后的结果只能输出最小的权值,不能打印最小生成树的路径) 本Tianc在刚学的 ...
- Roslyn还出现这么低级的错误,不应该呀!
前几天对Dora.Interception作了简单的重构,想提供C#脚本来定义Interception Policy,毫无疑问微软提供的编译平台Roslyn使C#脚本化提供了支持.但是没有想到随便尝试 ...
- 如何利用GitHub搜索敏感信息
如何利用GitHub搜索敏感信息 背景: 最近总是能听到同事说在GitHub上搜到某个敏感信息,然后利用该信息成功的检测并发现某个漏洞,最后提交到对应的SRC(安全应急响应中心)换点money.顿时心 ...