Debugging
Debugging
Assert
def fact(x):
if x==0:
return 1
else:
return x*fact(x-1)
def half_fact(x)
return fact(x/2)
当按照以下调用时half_fact(5)
时传入fact中的是一个非整数,不会出发return条件,会一直递归下去。
使用asset
将错误尽早发现抛出
def fact(x):
assert isinstance(x,int)
assert x>=0
if x==0:
return 1
else:
return x*fact(x-1)
def half_fact(x)
return fact(x/2)
但是assert
也具有一些局限性
- 需要不变量,我们显然知道这个量的所有条件,并在检查时保证条件永远正确
- 断言检查基于对代码存在的理解
- 断言并不会帮助人理解代码如何工作
- 断言最好加在自己的代码里而不是别人的,(对于debug来说6个月前的你已不再是现在的你)
Testing
- 发现你代码中的错误
- 对代码中某些组件有信心
- 缩小debug的范围
- 记录代码怎么工作
Doctests
def fib(n):
"""Fibonacci
>>> fib(2)
1
>>> fib(10)
55
"""
使用:执行python3 -m doctest file.py
即可
局限:
- 不能太多
- 对于数据输出的格式有限制
Print debugging
与ok连用:
def fact(x):
print("x=",x)
if x==0:
return 1
else:
return x*fact(x-1)
def half_fact(x)
return fact(x/2)
这在文档测试中无法通过的,fact(2)报错类似于
Error: expected
2
but got
x=2
x=1
x=0
2
而ok
测试会忽略掉print语句,同时执行文档测试
交互式debugging
python3 -i file.py
- 之后可以测试任意python指令
同时交互也可集成ok
python3 ok -q whatever -i
错误类型
Traceback
def f(x):
1/0
def g(x):
f(x)
def h(x):
g(x)
print(h(2))
阅读回溯:
- 读底部错误信息
- 从低到高看错误信息,看是哪一行出错
Exceptions
抛异常
断言 assert <exporession>, <string>
若表达式不为真,那么返回<string>
raise语句 raise <expression>
<expression>
必须是基类的子类(因为其对象属性)
异常处理
try语句
try:
<try suite>
exception <expression class> as <name>
<except suite>
demo
要特别关注的是异常处理的顺序