Python学习笔记调试之日志
随笔记录方便自己和同路人查阅。
#------------------------------------------------我是可耻的分割线-------------------------------------------
如果你曾经在代码中加入 print() 语句,在程序运行时输出某些变量的值,你就使用了记日志的方式来调试代码。记日志是一种很好的方式,
可以理解程序中发生的事,以及事情发生的顺序。Python 的 logging 模块使得你很容易创建自定义的消息记录。这些日志消息将描述程序执行
何时到达日志函数调用,并列出你指定的任何变量当时的值。另一方面,缺失日志信息表明有一部分代码被跳过,从未执行。
#------------------------------------------------我是可耻的分割线-------------------------------------------
1、使用日志模块
启用logging模块,在程序运行时将日志信息显示在屏幕上,示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #! python 3 # -*- coding:utf-8 -*- # Autor: Li Rong Yang import logging logging.basicConfig(level = logging.DEBUG, format = ' %(asctime)s - %(levelname)s - %(message)s' ) #用日志提示程序开始 logging.debug( 'Start of program' ) def factorial(n): # 用日志提示函数开始 logging.debug( 'Start of factorial(%s%%)' % (n)) total = 1 for i in range (n + 1 ): total * = i # 用日志提示函数内循环的变量结果 logging.debug( 'i is ' + str (i) + ',total is ' + str (total)) # 用日志提示函数结束 logging.debug( 'End of factorial(%s%%)' % (n)) return total print (factorial( 5 )) #用日志提示程序结束 logging.debug( 'End of program' ) |
运行结果:
根据运行结果,我们很直观的看出了问题所在,total一直的0。
2、不要使用print()调试
输入 import logging 和 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')有一点不方便。你可能想使用 print() 调用代替,但不要屈服于这种诱惑!
在调试完成后,你需要花很多时间,从代码中清除每条日志消息的 print() 调用。你甚至有可能不小心删除一些 print() 调用,而它们不是用来产生日志消息的。日志消息的好处在于,你可以随心所欲地在程
序中想加多少就加多少,稍后只要加入一次 logging.disable(logging.CRITICAL)调用,就可以禁止日志。不像 print(),logging 模块使得显示和隐藏日志信息之间的切换变得很容易。
停用日志,示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #! python 3 # -*- coding:utf-8 -*- # Autor: Li Rong Yang import logging logging.basicConfig(level = logging.DEBUG, format = ' %(asctime)s - %(levelname)s - %(message)s' ) logging.disable(logging.CRITICAL) #用日志提示程序开始 logging.debug( 'Start of program' ) def factorial(n): # 用日志提示函数开始 logging.debug( 'Start of factorial(%s%%)' % (n)) total = 1 for i in range (n + 1 ): total * = i # 用日志提示函数内循环的变量结果 logging.debug( 'i is ' + str (i) + ',total is ' + str (total)) # 用日志提示函数结束 logging.debug( 'End of factorial(%s%%)' % (n)) return total print (factorial( 5 )) #用日志提示程序结束 logging.debug( 'End of program' ) |
运行结果:
3、日志级别
“日志级别”提供了一种方式,按重要性对日志消息进行分类。5 个日志级别如表10-1 所示,从最不重要到最重要。利用不同的日志函数,消息可以按某个级别记入日志。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #! python 3 # -*- coding:utf-8 -*- # Autor: Li Rong Yang import logging logging.basicConfig(level = logging.DEBUG, format = ' %(asctime)s - %(levelname)s - %(message)s' ) #最低级别。用于小细节。通常只有在诊断问题时,你才会关心这些消息 logging.debug( 'Some debugging details.' ) #用于记录程序中一般事件的信息,或确认一切工作正常 logging.info( 'The logging module is working.' ) #用于表示可能的问题,它不会阻止程序的工作,但将来可能会 logging.warning( 'An error message is about to be logged.' ) #用于记录错误,它导致程序做某事失败 logging.error( 'An error has occurred.' ) #最高级别。用于表示致命的错误,它导致或将要导致程序完全停止工作 logging.critical( 'The program is unable to recover!' ) |
运行结果:
日志消息作为一个字符串,传递给这些函数。日志级别是一种建议。归根到底,还是由你来决定日志消息属于哪一种类型。
日志级别的好处在于,你可以改变想看到的日志消息的优先级。向basicConfig()函数传入logging.DEBUG作为level关键字参数,这将显示所有日志级别的消息
(DEBUG是最低的级别)。但在开发了更多的程序后,你可能只对错误感兴趣。在这种情况下,可以将 basicConfig() 的 level 参数设置为 logging.ERROR,这将只
显示 ERROR和 CRITICAL 消息,跳过 DEBUG、INFO 和 WARNING 消息。
4、将日志信息写入文件
虽然日志消息很有用,但它们可能塞满屏幕,让你很难读到程序的输出。将日志信息写入到文件,让屏幕保持干净,又能保存信息,这样在运行程序后,可以阅读
这些信息。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #! python 3 # -*- coding:utf-8 -*- # Autor: Li Rong Yang import logging logging.basicConfig(filename = 'd:\\MyProgramLog.txt' ,level = logging.DEBUG, format = ' %(asctime)s - %(levelname)s - %(message)s' ) #用日志提示程序开始 logging.debug( 'Start of program' ) def factorial(n): # 用日志提示函数开始 logging.debug( 'Start of factorial(%s%%)' % (n)) total = 1 for i in range (n + 1 ): total * = i # 用日志提示函数内循环的变量结果 logging.debug( 'i is ' + str (i) + ',total is ' + str (total)) # 用日志提示函数结束 logging.debug( 'End of factorial(%s%%)' % (n)) return total print (factorial( 5 )) #用日志提示程序结束 logging.debug( 'End of program' ) |
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异