如何在Python中调试代码?

来源:网站主作者:IT柏拉图头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何在Python中调试代码?》,敬请观看详情。程序跑到一半抛出莫名其妙的异常,或者变量值跟预期完全对不上,这时候硬看代码效率很低。Python标准库自带的pdb模块就是专门解决这类问题的交互式调试器,它能在程序运行中暂停执行,让你逐行查看调用栈和变量状态。除了在命令行里敲命令,也可以直接在代码里插断点,或者用IDE的图形化工具辅助。掌握几种常用调试方式,比反复加打印语句省时间得多,也能更快定位逻辑漏洞和第三方库里的隐藏问题。

写Python代码时,逻辑错误和运行时异常几乎无法避免。相比在每一行都写print把变量打出来,使用专业的调试工具可以动态暂停程序、观察上下文并单步执行,从而精准定位问题根源。本文围绕标准库与常用实践,介绍在Python中调试代码的几种有效方式。

如何在Python中调试代码?

使用pdb进行交互式调试

pdb是Python内置的调试器,无需安装任何第三方包即可使用。它提供了一套类似GDB的命令,可以在程序执行到某处时停下来,检查局部变量、全局变量以及调用栈信息。最常见的做法是在代码中引入pdb模块并调用set_trace方法,程序运行到这里会进入交互模式。

下面是一段有逻辑错误的示例,我们在计算平均值时误把分母写成零,通过pdb可以清楚看到变量状态:

import pdb

def calc_average(nums):
    total = 0
    for n in nums:
        total += n
    # 故意写错的分母
    pdb.set_trace()
    avg = total / 0
    return avg

result = calc_average([10, 20, 30])
print(result)

运行后程序会在set_trace处暂停,此时可以输入命令n执行下一行,输入p total打印total的值,输入l查看周围代码。如果发现分母应为len(nums),就能快速修正。pdb还支持b 行号设置断点、c继续运行、s进入函数内部等,熟练后调试效率很高。

pdb常用命令对照

命令作用
n执行下一行,不进入函数
s单步进入函数调用
c继续执行直到下一个断点
p 变量名打印变量当前值
l列出当前执行位置附近的代码
q退出调试器并终止程序

虽然pdb是命令行工具,但它对远程服务器上无图形界面的环境特别友好。当生产环境出现偶发错误,而又不能本地复现,通过ssh连上后使用pdb定位往往比加日志更快。

利用breakpoint函数快速插桩

从Python 3.7开始,标准库提供了内置函数breakpoint,它相当于pdb.set_trace的简化写法,而且可以通过环境变量PYTHONBREAKPOINT切换底层调试后端。这意味着以后想换用其他调试器,代码无需改动。

示例代码如下,逻辑是找出列表中第一个大于阈值的数:

def find_first_bigger(items, threshold):
    for i, val in enumerate(items):
        if val > threshold:
            breakpoint()
            return i
    return -1

idx = find_first_bigger([3, 7, 12, 5], 6)
print(idx)

在支持的环境中,breakpoint会直接拉起pdb。如果设置了PYTHONBREAKPOINT=0,则该函数变成空操作,方便在正式环境一键关闭所有断点。相比以前要写import pdb; pdb.set_trace(),如今只写breakpoint更加简洁,也减少了误提交调试语句的概率。

不过要注意,breakpoint虽好,但提交到代码仓库前应当确认是否删掉,否则别人运行你的脚本会意外卡在调试界面。团队可借助预提交钩子扫描关键字来防止遗漏。

借助IDE图形化调试

如果你使用PyCharm、VS Code等现代编辑器,图形化调试比命令行直观很多。以VS Code为例,在行号左侧单击即可打红点设置断点,按F5启动调试,侧边栏实时显示变量、调用栈和监视表达式。对于复杂对象,还能展开属性树,不必手动敲打印命令。

图形化工具背后其实也是调用debugpy之类的适配器,与pdb原理相通,但降低了记忆命令的成本。下面展示一个在VS Code里调试类方法的场景:

class Counter:
    def __init__(self):
        self.count = 0

    def add(self, step):
        self.count += step
        return self.count

c = Counter()
c.add(5)
c.add(3)

add方法内部设断点后,每次调用都能看到self.count的变化过程。如果怀疑某次调用传参异常,可在监视窗口写step > 10这样的表达式,调试器会在条件满足时暂停。这种条件断点功能在循环次数极多时尤为实用,避免手动一直按继续。

命令行与图形界面如何选择

  • 服务器无界面场景:优先pdb或breakpoint,通过终端交互。
  • 本地开发阶段:用IDE图形调试,节省时间且不易看错变量。
  • 临时排查脚本:直接加breakpoint,事后再清理。

两种方式并非互斥,很多开发者本地用IDE、线上用pdb,根据环境灵活切换即可。

通过日志与异常追踪辅助调试

调试并不总意味着暂停程序。有些问题只在特定请求或并发下出现,这时候用logging模块输出带时间戳的日志,比断点更合适。同时,遇到未捕获异常时,Python默认的traceback已经指出出错文件和行号,结合pdb的post_mortem功能还能事后调查。

以下示例演示如何用pdb.post_mortem在程序崩溃后进入现场:

import pdb, traceback

def risky():
    return 1 / 0

try:
    risky()
except Exception:
    traceback.print_exc()
    pdb.post_mortem()

执行后异常被打印,并立即进入pdb界面,你可以检查崩溃那一刻的局部变量。对于难以复现的bug,这种“死后验尸”的方式非常有价值。此外,建议在关键路径用logging.info记录输入输出,而不是零散的print,这样既方便调试,也利于上线后排查。

综合来看,Python调试的手段非常丰富。从标准库pdb、breakpoint到IDE图形工具,再到日志与异常分析,各自覆盖不同场景。理解其底层机制后,遇到问题时便能挑最合适的那一种,而不是只会盲目加打印。

Python调试pdb断点调试修改时间:2026-08-08 19:15:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。