写点什么

翻译:《实用的 Python 编程》08_03_Debugging

用户头像
codists
关注
发布于: 2021 年 04 月 11 日
翻译:《实用的Python编程》08_03_Debugging

目录 | 上一节 (8.2 日志) | 下一节 (9 包)

8.3 调试

调试建议

假设程序崩溃了:


bash % python3 blah.pyTraceback (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.pyTraceback (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 crashAttributeError: 'int' object has no attribute 'append'
复制代码


不过,回溯信息并不总是那么易于阅读或理解。


专业建议:将整个回溯粘贴到谷歌。

使用交互式解释器(REPL)

执行脚本的 时候,可以使用选项 -i 使 Python 保持存活(keep alive)。


bash % python3 -i blah.pyTraceback (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()

在调试解释器下运行程序

也可以在调试器下运行整个程序:


bash % python3 -m pdb someprogram.py
复制代码


上述操作会在第一行语句之前自动进入调试器,允许设置断点和修改配置。


常见的调试器命令:


(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
复制代码


断点的位置可以用下列任意一种方式进行表示:


(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

发布于: 2021 年 04 月 11 日阅读数: 34
用户头像

codists

关注

公众号:编程人 2021.01.14 加入

Life is short, You need Python

评论

发布
暂无评论
翻译:《实用的Python编程》08_03_Debugging