简介
代码永远不可能完美。你总会遇到错误。代码调试是一项你需要学习的技能。
This tutorial is from open-source community. Access the source code
💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版
代码永远不可能完美。你总会遇到错误。代码调试是一项你需要学习的技能。
所以,你的程序崩溃了……
$ 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'
现在该怎么办?!
最后一行是崩溃的具体原因。
## 崩溃原因
然而,它并不总是易于阅读或理解。
专业提示:将整个回溯信息粘贴到谷歌中。
使用选项-i
在执行脚本时保持 Python 处于活动状态。
$ 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'
>>>
它会保留解释器的状态。这意味着在程序崩溃后你可以四处查看。检查变量值和其他状态。
使用print()
进行调试非常常见。
提示:确保你使用repr()
def spam(x):
print('DEBUG:', repr(x))
...
repr()
会显示值的准确表示形式,而不是美观的打印输出。
>>> from decimal import Decimal
>>> x = Decimal('3.4')
## 不使用 `repr`
>>> print(x)
3.4
## 使用 `repr`
>>> print(repr(x))
Decimal('3.4')
>>>
你可以在程序中手动启动调试器。
def some_function():
...
breakpoint() ## 进入调试器(Python 3.7+)
...
这会在breakpoint()
调用处启动调试器。
在早期的 Python 版本中,你是这样做的。你有时会在其他调试指南中看到这种方法。
import pdb
...
pdb.set_trace() ## 代替 `breakpoint()`
...
你也可以在调试器下运行整个程序。
$ python3 -m pdb someprogram.py
它会在第一条语句之前自动进入调试器,让你能够设置断点并更改配置。
常见的调试器命令:
(Pdb) help ## 获取帮助
(Pdb) w(here) ## 打印堆栈跟踪
(Pdb) d(own) ## 下移一个堆栈层级
(Pdb) u(p) ## 上移一个堆栈层级
(Pdb) b(reak) loc ## 设置断点
(Pdb) s(tep) ## 执行一条指令
(Pdb) c(ontinue) ## 继续执行
(Pdb) l(ist) ## 列出源代码
(Pdb) a(rgs) ## 打印当前函数的参数
(Pdb)!statement ## 执行语句
对于断点,位置可以是以下之一。
(Pdb) b 45 ## 当前文件的第45行
(Pdb) b file.py:45 ## file.py的第45行
(Pdb) b foo ## 当前文件中的函数foo()
(Pdb) b module.foo ## 模块中的函数foo()
能运行就行。发布吧!
恭喜你!你已经完成了调试实验。你可以在 LabEx 中练习更多实验来提升你的技能。