当前位置: 首页 > news >正文

python基础-11-调试程序

文章目录

  • 【README】
  • 【11】调试
    • 【11.1】抛出异常
      • 【11.1.1】抛出异常代码块
    • 【11.2】获取回溯字符串
      • 【11.2.1】traceback获取异常回溯信息
    • 【11.3】断言
      • 【11.3.1】断言代码示例
    • 【11.4】日志(使用logging模块)
      • 【11.4.1】使用logging模块操作日志
      • 【11.4.3】日志级别(按照消息重要性对日志分类)
      • 【11.4.4】禁用日志
      • 【11.4.5】把日志记录到文件
    • 【11.5】调试程序(调试器模式)
    • 【11.6】小结

【README】

本文总结自《python编程快速上手-让繁琐工作自动化》第11章,非常棒的一本书,墙裂推荐;



【11】调试

【11.1】抛出异常

1)回顾捕获异常代码示例(try-exception代码块):

# 异常处理
print('\n=== 异常处理 ===')
def handleExp(operator):
    try:
        return 42 / operator
    except ZeroDivisionError:
        print(str(operator) + ', 导致0除异常')
        return None

print(handleExp(1))
print(handleExp(2))
# 0除异常
print(handleExp(0))
print(handleExp(3))

【11.1.1】抛出异常代码块

1)抛出异常代码:

  • 使用raise关键字;
  • 对Exception函数调用;
  • 传递给Exception函数字符串,包含错误信息;

# 定义函数,抛出异常
def callPhone(phoneNumber):
    if phoneNumber == '110':
        raise Exception("110不是合法电话号码")
    elif phoneNumber == '120':
        raise Exception("120不是合法电话号码")
    print('Calling Phone Number:', phoneNumber)

def iphone(phoneNumber):
    try:
        callPhone(phoneNumber)
    except Exception as error:
        print("exception happened: " + str(error))

# 调用函数
iphone("110")
iphone("120")
iphone("130")

# exception happened: 110不是合法电话号码
# exception happened: 120不是合法电话号码
# Calling Phone Number: 130


【11.2】获取回溯字符串

1)异常的回溯字符串包括:错误信息, 导致该错误的代码行号,以及导致该错误的函数调用的序列,这个序列称为调用栈;

# 11.2 获取回溯字符串
def dinner():
    bacon()
def bacon():
    raise Exception('this is the error msg.')

# 调用函数,打印异常的回溯信息
dinner()

# Traceback (most recent call last):
#   File "D:\studynote\00-ai-llm\workbench\PythonBasicStudy\chapter11\1102.py", line 9, in <module>
#     dinner()
#   File "D:\studynote\00-ai-llm\workbench\PythonBasicStudy\chapter11\1102.py", line 4, in dinner
#     bacon()
#   File "D:\studynote\00-ai-llm\workbench\PythonBasicStudy\chapter11\1102.py", line 6, in bacon
#     raise Exception('this is the error msg.')
# Exception: this is the error msg.

【11.2.1】traceback获取异常回溯信息

1)引入 traceback模块;

import traceback
from pathlib import Path

def dinnerWithTraceBack():
    try:
        dinner()
    except:
        errorFile = open(Path.cwd() / 'errorInfo.txt', 'w')
        # 把异常的回溯信息写入文件
        errorFile.write(traceback.format_exc())
        errorFile.close()
        print('the traceback info was written to errorInfo.txt')


# 调用函数,使用traceback收集异常信息
dinnerWithTraceBack()

【补充】写入文件errorInfo.txt的内容就是11.2 Traceback (most recent call last): 打印出的异常栈内容;



【11.3】断言

1)断言:是健全性检查,用于确保代码没有做什么明显错误的事情;

  • 断言检查由assert语句执行; 若检查失败,会抛出异常;

2)在代码中, assert包含如何部分:

  • assert关键字;
  • 条件(求值为True或False的表达式)
  • 逗号
  • 当条件为False显示的字符串;

3)断言与异常不同,异常可以按需捕获;而断言不应该被try-except代码块捕获,如果assert失败,程序就应该崩溃

  • 断言针对的是程序员的错误,而不是用户错误;
  • 断言只能在程序开发时失败,用户永远都不会在完成的程序中看到断言错误;
  • 对于正常运行中的错误,不应该使用assert来检测它;不应该用assert来引发异常,因为用户可以选择关闭断言;

【11.3.1】断言代码示例

# 定义函数,使用断言做判断
# (在生产环境中不要参考该代码,仅做测试,因为运行时的程序不应该使用断言,而在程序或应用启动时可以使用)
def callPhoneWithAssert(phoneNumber):
    assert len(phoneNumber) == 11, phoneNumber + 'is not a valid phone number'
    print('Calling Phone Number:', phoneNumber)

# 调用函数
callPhoneWithAssert('110')

【断言结果】

Traceback (most recent call last):
  File "D:\studynote\00-ai-llm\workbench\PythonBasicStudy\chapter11\1103.py", line 8, in <module>
    callPhoneWithAssert('110')
  File "D:\studynote\00-ai-llm\workbench\PythonBasicStudy\chapter11\1103.py", line 4, in callPhoneWithAssert
    assert len(phoneNumber) == 11, phoneNumber + 'is not a valid phone number'
           ^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 110is not a valid phone number


【11.4】日志(使用logging模块)

【11.4.1】使用logging模块操作日志

1)使用logging模块打印日志

import logging

# 设置日志格式
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
def callPhoneWithLogging(phoneNumber):
    logging.debug('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.info('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.warning('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.error('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.critical('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    if (len(phoneNumber) != 11):
        logging.error('%s is not a valid phone number', phoneNumber)
    print('Calling Phone Number:', phoneNumber)

# 调用函数,打印日志
callPhoneWithLogging('110')

【打印结果】

2025-04-05 07:07:03 - root - DEBUG - calling callPhoneWithLogging() , phoneNumber:110
2025-04-05 07:07:03 - root - INFO - calling callPhoneWithLogging() , phoneNumber:110
2025-04-05 07:07:03 - root - WARNING - calling callPhoneWithLogging() , phoneNumber:110
2025-04-05 07:07:03 - root - ERROR - calling callPhoneWithLogging() , phoneNumber:110
2025-04-05 07:07:03 - root - CRITICAL - calling callPhoneWithLogging() , phoneNumber:110
2025-04-05 07:07:03 - root - ERROR - 110 is not a valid phone number
Calling Phone Number: 110

【11.4.3】日志级别(按照消息重要性对日志分类)

1)5个日志级别,从最不重要到最重要;利用不同日志函数,消息可以按照某个级别记入日志;

2)日志重要性从低到高:

  • DEBUG;
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

在这里插入图片描述


【11.4.4】禁用日志

1)调用logging.disable(level):禁止该级别和更低级别的所有日志消息;

  • 如果想要禁用所有日志,可以调用logging.disable(CRITICAL)

2)禁用 ERROR及以下日志的写法:

import logging

# 设置日志格式
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
# 禁用 ERROR 及以下日志的写法
logging.disable(logging.ERROR) 
def callPhoneWithLogging(phoneNumber):
    logging.debug('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.info('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.warning('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.error('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    logging.critical('calling callPhoneWithLogging() , phoneNumber:%s', phoneNumber)
    if (len(phoneNumber) != 11):
        logging.error('%s is not a valid phone number', phoneNumber)
    print('Calling Phone Number:', phoneNumber)

# 调用函数,打印日志
callPhoneWithLogging('110')

【打印结果】

Calling Phone Number: 110
2025-04-05 07:08:38 - root - CRITICAL - calling callPhoneWithLogging() , phoneNumber:110

【11.4.5】把日志记录到文件

logging.basicConfig(filename="diyLog.txt", level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')


【11.5】调试程序(调试器模式)

1)调试模式的按钮:

  • continue:程序执行到终点或下一个断点;
  • step In:执行到下一行代码,然后再次暂停; 如果下一行代码是函数调用,则进入到函数并跳转到函数的第一行代码;
  • step over:执行到下一行代码, 若下一行代码是函数调用,则跳过;
  • step out:跳出当前函数调用;
  • stop:终止调试;

在这里插入图片描述



【11.6】小结

1)断言,异常,日志和调试器都是在程序中发现和预防bug的有效工具;

  • 断言:assert
  • 异常:try-except代码块去捕获
  • 日志:logging
http://www.dtcms.com/a/113732.html

相关文章:

  • DrissionPage高级技巧:从爬虫到自动化测试
  • Python FastApi(13):APIRouter
  • 操作系统知识点(二)
  • 超级科学软件实验室(中国) : Super Scientific Software Laboratory (SSSLab)
  • Vue2与Vue3不同
  • Deformable DETR(复习专用)
  • 基于Spark的哔哩哔哩舆情数据分析系统
  • 【RK3588 嵌入式图形编程】-SDL2-扫雷游戏-创建网格
  • liunx输入法
  • 网安小白筑基篇五:web后端基础之Python(补充Python的魔术方法)
  • Scade One - 将MBD技术从少数高安全领域向更广泛的安全嵌入式软件普及
  • 使用MATIO库读取Matlab数据文件中的cell结构数据
  • 【设计模式】命令模式
  • mine craft经典信封
  • 力扣刷题-热题100题-第31题(c++、python)
  • 博途 TIA Portal之1200做主站与200SMART的S7通讯
  • 《减压宝典》Python篇
  • leetcode每日一题:替换子串得到平衡字符串
  • vue3实现markdown预览和编辑
  • Cursor 无限续杯 Windows版
  • 智能体开发实战指南:提示词设计、开发框架与工作流详解
  • ROS多设备交互
  • 用C语言控制键盘上的方向键
  • LightRAG核心原理和数据流
  • Cisco Packet Tracer 8.0(新版)
  • 【神经网络】python实现神经网络(三)——正向学习的模拟演练
  • Unity插件SuperScrollView详解(进阶篇)
  • MySQL篇(五)MySQL主从同步原理深度剖析
  • 面试算法高频03-递归
  • day 8 TIM定时器