Debugging

发布时间 2024-01-03 20:05:31作者: viewoverlook

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也具有一些局限性

  1. 需要不变量,我们显然知道这个量的所有条件,并在检查时保证条件永远正确
  2. 断言检查基于对代码存在的理解
    • 断言并不会帮助人理解代码如何工作
    • 断言最好加在自己的代码里而不是别人的,(对于debug来说6个月前的你已不再是现在的你)

Testing

  • 发现你代码中的错误
  • 对代码中某些组件有信心
  • 缩小debug的范围
  • 记录代码怎么工作

Doctests

def fib(n):
"""Fibonacci
>>> fib(2)
1
>>> fib(10)
55
"""

使用:执行python3 -m doctest file.py即可

局限:

  1. 不能太多
  2. 对于数据输出的格式有限制

与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))

阅读回溯:

  1. 读底部错误信息
  2. 从低到高看错误信息,看是哪一行出错

Exceptions

抛异常

断言 assert <exporession>, <string> 若表达式不为真,那么返回<string>
raise语句 raise <expression> <expression>必须是基类的子类(因为其对象属性)

异常处理

try语句

try:
	<try suite>
exception <expression class> as <name>
	<except suite>

demo

要特别关注的是异常处理的顺序