
教程文档【免费下载链接】practical-pythonPractical Python Programming (course by dabeaz)项目地址https://gitcode.com/gh_mirrors/pr/practical-python点击查看免费下载本篇技术指南来自 Practical Python Programming 课程作者 dabeaz的第 8.3 节聚焦程序崩溃后的完整调试工作流如何读懂 Traceback 定位根因、如何用python3 -i在崩溃现场保留解释器状态、如何用print()repr()快速插桩、以及如何通过breakpoint()与python3 -m pdb进入交互式调试器。读完本文你将掌握一套从程序崩了到找到并修复 bug的可操作方案并能直接在本仓库的report.py/fileparse.py实战代码上应用这些技巧。程序崩溃之后第一件事是读懂 Traceback程序崩了Shell 里会吐出一大段Traceback。例如bash % python3 blah.py Traceback (most recent call last): File blah.py, line 13, in ? foo() File blah.py, line 10, in foo bar() File blah.py, line 7, in bar spam() File blah.py, 4, in spam line x.append(3) AttributeError: int object has no attribute append现在怎么办先别慌最后一行的异常类型与消息就是崩溃的直接原因bash % python3 blah.py Traceback (most recent call last): File blah.py, line 13, in ? foo() File blah.py, line 10, in foo bar() File blah.py, line 7, in bar spam() File blah.py, 4, in spam line x.append(3) # Cause of the crash AttributeError: int object has no attribute append这里根因是x是一个int却对它调用了append()。回溯中的每一帧File blah.py, line N, in func对应一次函数调用从下往上是由内向外的调用链——最内层帧line 4才是真正出错的语句。不过Traceback 并不总是那么直观易懂。PRO TIP把整段 Traceback 原样粘贴到搜索引擎里搜大概率能立刻找到同类问题与社区讨论这是快速定位常见异常最有效的手段之一。保持现场用python3 -i在崩溃后进入 REPL读懂异常信息只是第一步很多时候你还需要亲眼看看崩溃时各变量的值。Python 提供了-i选项脚本执行完毕后即使崩溃解释器不会退出而是直接进入交互式 REPL。bash % python3 -i blah.py Traceback (most recent call last): File blah.py, line 13, in ? foo() File blah.py, line 10, in foo bar() File blah.py, line 7, in bar spam() File blah.py, 4, in spam line x.append(3) AttributeError: int object has no attribute append 关键在于提示符解释器状态被完整保留崩溃时栈帧中的局部变量、全局变量都还在你可以直接在提示符下翻找现场检查各个变量的取值和其他状态 x 3 type(x) class int这比凭空猜测要可靠得多——先确认数据到底是什么再决定怎么修。打印调试print()配合repr()才准确往代码里插print()是最常见的调试手段但有一个关键陷阱务必使用repr()而不是直接打印。def spam(x): print(DEBUG:, repr(x)) ...为什么要用repr()因为它给出的是值的精确、无歧义表示而不是面向用户的漂亮输出。经典例子是Decimal from decimal import Decimal x Decimal(3.4) # NO repr print(x) 3.4 # WITH repr print(repr(x)) Decimal(3.4) print(x)显示3.4你完全看不出这是个Decimal还是float而print(repr(x))显示Decimal(3.4)一眼就知道它的真实类型与构造方式。调试字符串时同样如此——repr()能让你看清看不见的空白字符、转义序列与引号。记住这条经验用repr()打印出来的调试信息永远不会骗你。手动进入调试器breakpoint()与pdb.set_trace()打印调试适合粗定位而真正逐行查看执行流程则需要调试器。你可以在程序里任意位置手动启动调试器def some_function(): ... breakpoint() # Enter the debugger (Python 3.7) ...breakpoint()是Python 3.7的内置函数执行到这里时程序会暂停并进入pdbPython 调试器然后你就可以逐行检查状态。这也正是本仓库课程环境的要求——课程设置说明 中要求 Python 3.6 或更新版本即可若使用 3.6 则需用下面的旧式写法。在更早的 Python 版本里你只能这样做很多老调试教程里仍会提到import pdb ... pdb.set_trace() # Instead of breakpoint() ...注意在新版本中breakpoint()是首选它实际上调用sys.breakpointhook()允许通过环境变量或sys.breakpointhook重定向到其他调试器如pdb、ipdb可扩展性更好。在调试器下运行整个程序python3 -m pdb除了在代码里埋点你还可以让整个程序在调试器下运行bash % python3 -m pdb someprogram.py程序会在第一条语句执行之前自动进入调试器允许你先设置断点、调整配置再让程序跑起来。这对于难以确定埋点位置的场景非常实用。pdb 常用命令速查进入(Pdb)提示符后下面这套命令足以覆盖绝大多数调试场景括号内为完整拼写(Pdb) help # Get help (Pdb) w(here) # Print stack trace (Pdb) d(own) # Move down one stack level (Pdb) u(p) # Move up one stack level (Pdb) b(reak) loc # Set a breakpoint (Pdb) s(tep) # Execute one instruction (Pdb) c(ontinue) # Continue execution (Pdb) l(ist) # List source code (Pdb) a(rgs) # Print args of current function (Pdb) !statement # Execute statement逐条解读help查看调试器的全部内置帮助w打印当前栈回溯确认自己身处哪一层调用d/u在调用栈的层级间向下/向上移动从而检查不同函数帧内的变量b在指定位置设置断点s单步执行一条指令会进入函数内部c继续运行直到下一个断点或程序结束l列出当前位置附近的源代码方便对照行号a打印当前函数的参数值!statement在调试器中执行任意 Python 语句例如!x 42可以直接修改变量用于临时修补现场。断点的位置语法b(reak)的loc参数支持四种写法灵活覆盖按行、按文件、按函数的定位需求(Pdb) b 45 # Line 45 in current file (Pdb) b file.py:45 # Line 45 in file.py (Pdb) b foo # Function foo() in current file (Pdb) b module.foo # Function foo() in a moduleb 45在当前文件第 45 行设断点b file.py:45在指定文件的第 45 行设断点文件需可被 import 或已加载b foo在当前文件中的函数foo()入口设断点b module.foo在某个模块里的函数foo()入口设断点。结合本仓库实战给fileparse.py的坏数据定位调试技巧需要落到真实代码上才有价值。本仓库中就有现成的练习场景fileparse.py的parse_csv()在解析 CSV 时会对每行做类型转换遇到坏数据会在except ValueError分支里用日志记录问题行。8.2 节的完整实现见 Solutions/8_2/fileparse.py# fileparse.py import csv import logging log logging.getLogger(__name__) def parse_csv(lines, selectNone, typesNone, has_headersTrue, delimiter,, silence_errorsFalse): ... for rowno, row in enumerate(rows, 1): ... if types: try: row [func(val) for func, val in zip(types, row)] except ValueError as e: if not silence_errors: log.warning(Row %d: Couldnt convert %s, rowno, row) log.debug(Row %d: Reason %s, rowno, e) continue而report.py中的read_portfolio()会调用它读取持仓数据Solutions/8_2/report.py。当数据文件存在缺失字段时——例如仓库里的 Work/Data/missing.csv第 4 行MSFT,,51.23的shares字段是空的——程序并不会崩溃但转换会失败 import report a report.read_portfolio(Data/missing.csv) Row 4: Bad row: [MSFT, , 51.23] Row 7: Bad row: [IBM, , 70.44] 这正是程序没崩但行为可疑的场景。要深入追查为什么无法转换为整数可以把breakpoint()临时插在parse_csv的except ValueError分支里或者用python3 -m pdb运行report.py在parse_csv的入口设断点b parse_csv然后s单步跟进、用a查看types与row的参数值用l对照源码——你会发现int()抛出ValueError: invalid literal for int() with base 10: 根因一目了然。如果只是想先看现场python3 -i配合report.read_portfolio(Data/missing.csv)也能让你在 REPL 里逐个检查rowno与row的值。对比正常数据文件 Work/Data/portfolio.csv所有字段完整就能确认问题只出在坏数据行——这就是用调试手段验证假设的完整闭环。练习 8.4Bugs? What Bugs?本节的课程练习只有一句话却道出了调试哲学的另一面It runs. Ship it!程序能跑就发版——这是没有明显 bug时的务实态度。它与前面的测试章节相辅相成8.1 节Notes/08_Testing_debugging/01_Testing.md教你用unittest提前拦截回归仓库中有完整的 Solutions/8_1/test_stock.py 可对照8.2 节Notes/08_Testing_debugging/02_Logging.md教你把诊断信息交给logging而非散落的print。而本节则是在 bug 真的发生时用 Traceback、REPL、repr()与pdb组成的调试工具箱快速定位。三者合起来才是完整的工程质量闭环测试防患于未然日志提供事后线索调试器解决当下问题。小结一套完整的调试工作流把本节技巧串成一条可复用的流程读异常先看 Traceback 最后一行确定异常类型与根因语句必要时整段粘贴到搜索引擎保现场用python3 -i让崩溃后解释器存活直接在 REPL 检查变量插桩需要快速确认某个值时用print(DEBUG:, repr(x))打印精确表示进调试器代码里放breakpoint()Python 3.7或pdb.set_trace()旧版本在关键位置暂停全程序调试用python3 -m pdb someprogram.py在首条语句前进入调试器配合b/s/c/l/a/!逐步排查验证修复用unittest与logging8.1、8.2 节固化修复结果防止问题回归。相关课程章节调试指南原文 | 测试章节 | 日志章节 | 课程目录。赞分享教程文档【免费下载链接】practical-pythonPractical Python Programming (course by dabeaz)项目地址https://gitcode.com/gh_mirrors/pr/practical-python点击查看免费下载相关推荐IRISMANPS3自定义固件游戏管理神器完整使用指南IRISMANPS3自定义固件游戏管理神器完整使用指南 IRISMAN是一款功能强大的PS3游戏管理器专为PlayStation®3自定义固件用户设计。作为嵌入式系统编程oh-my-openagent Python 调试实战从 pdb 到 debugpy 的完整排查指南oh my openagent Python 调试实战从 pdb 到 debugpy 的完整排查指南 导读本文以 oh my openagent 仓库中 d人工智能AI Agent代码智能体多智能体MCP ClientsAgent 编排Agentic Awesome Skills 使用指南从安装到熟练调用 2,000 技能的完整实战手册Agentic Awesome Skills 使用指南从安装到熟练调用 2,000 技能的完整实战手册 本文是面向普通用户的实操型指南。假设你已经完成了仓库AI 技能AI 插件上一篇Model-Optimizer Windows 基准测试解读ONNX INT4 量化在 RTX GPU 上的性能与精度全景分析下一篇如何5分钟解锁英雄联盟全皮肤R3nzSkin国服特供版完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考