文章目录
  1. 1. 错误处理
    1. 1.1. try…expcept…finally…
    2. 1.2. 调用栈
    3. 1.3. 记录错误
    4. 1.4. 抛出错误
  2. 2. 调试
    1. 2.1. print
    2. 2.2. 断言
    3. 2.3. logging
    4. 2.4. pdb、pdb.set_trace()
    5. 2.5. IDE
  3. 3. 单元测试
  4. 4. 文档测试

编写的错误叫Bug,必须要修复;用户操作出现的问题,需要提前检测和预防;还有一些文件操作、网络状况超出预期的,叫做异常,需要在程序中进行特殊处理. 所以,调试和测试非常必要.

错误处理

try…expcept…finally…

当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕.

错误应该有很多种类,如果发生了不同类型的错误,应该由不同的except语句块处理.

此外,如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句.

使用try…except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理.

调用栈

▶出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置.

记录错误

可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去.通过配置,logging还可以把错误记录到日志文件里,方便事后排查

抛出错误

因为错误是class,捕获一个错误就是捕获到该class的一个实例.因此,错误并不是凭空产生的,而是有意创建并抛出的.Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误.如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例.

只有在必要的时候才定义我们自己的错误类型.如果可以选择Python已有的内置的错误类型(比如ValueError,TypeError),尽量使用Python内置的错误类型.

还有一种特殊情况如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n

def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise

bar()

捕获错误后,输出了相应的错误信息,但是还使用了raise将错误抛出了.raise语句如果不带参数,就会把当前错误原样抛出,在except中raise一个Error,还可以把一种类型的错误转化成另一种类型.并且,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理.

调试

print

纯输出打印信息,但是实在是非常繁琐,全部代码都携带Print代码.

断言

和print类似的作用,但是相对来说,可以添加判断逻辑到断言里.

logging

比较灵活,和assert比,logging不会抛出错误,而且可以输出到文件.这就是logging的好处,它允许你指定记录信息的级别,有debug、info、warning、error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了.同理,指定level=WARNING后,debug和info就不起作用了.这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息.

logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件.

pdb、pdb.set_trace()

pdb方式以参数-m pdb启动.

pdb.set_trace()在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点,运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行.

IDE

不过最舒服的调试方式,当然还是集成开发环境啦,比方说Visual Studio Code、PyCharm.

单元测试

比较难,后期运用到了再进一步了解.可以在单元测试中编写两个特殊的setUp()和tearDown()方法。这两个方法会分别在每调用一个测试方法的前后分别被执行。

文档测试

比较麻烦,后期运用到了再进一步了解.
Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试.

文章目录
  1. 1. 错误处理
    1. 1.1. try…expcept…finally…
    2. 1.2. 调用栈
    3. 1.3. 记录错误
    4. 1.4. 抛出错误
  2. 2. 调试
    1. 2.1. print
    2. 2.2. 断言
    3. 2.3. logging
    4. 2.4. pdb、pdb.set_trace()
    5. 2.5. IDE
  3. 3. 单元测试
  4. 4. 文档测试