目录 | 上一节 (8.2 日志) | [下一节 (9 包)]()
8.3 调试
调试倡议
假如程序解体了:
<code class="bash">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'
那么当初该怎么办呢?
浏览回溯信息
最初一行是程序解体的具体起因:
<code class="bash">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'
不过,回溯信息并不总是那么易于浏览或了解。
业余倡议:将整个回溯粘贴到谷歌。
应用交互式解释器(REPL)
执行脚本的 时候,能够应用选项 -i
使 Python 放弃存活(keep alive)。
<code class="bash">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' >>>
选项 -i
能够保留解释器状态。这意味着能够在程序解体后查找错误信息。对变量的值和其它状态进行查看。
应用打印进行调试
应用 print()
函数进行调试十分常见。
倡议:确保应用的是 repr()
函数。
def spam(x): print('DEBUG:', repr(x)) ...
repr()
函数显示一个值的精确示意,而不是格局良好的输入。
>>> from decimal import Decimal >>> x = Decimal('3.4') # NO `repr` >>> print(x) 3.4 # WITH `repr` >>> print(repr(x)) Decimal('3.4') >>>
Python 的调试器
能够在程序内手动启动调试器(debugger)。
def some_function(): ... breakpoint() # Enter the debugger (Python 3.7+) ...
上述操作会在 breakpoint()
调用时启动调试器。
在 Python 的晚期版本中,可能会看到上面这样的调试指南:
import pdb ... pdb.set_trace() # Instead of `breakpoint()` ...
(译注:Python 3.7 之后,能够应用内置函数 breakpoint()
代替 import pdb; pdb.set_trace()
)
在调试解释器下运行程序
也能够在调试器下运行整个程序:
<code class="bash">bash % python3 -m pdb someprogram.py
上述操作会在第一行语句之前主动进入调试器,容许设置断点和批改配置。
常见的调试器命令:
<code class="code">(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
断点的地位能够用下列任意一种形式进行示意:
<code class="code">(Pdb) b 45 # Line 45 in current file (Pdb) b file.py:45 # Line 34 in file.py (Pdb) b foo # Function foo() in current file (Pdb) b module.foo # Function foo() in a module
练习
练习 8.4:Bugs? 什么是 Bugs?
有 bug,咱们就解决 bug(It runs. Ship it!)。
目录 | 上一节 (8.2 日志) | [下一节 (9 包)]()
注:残缺翻译见 https://github.com/codists/practical-python-zh