错误处理
try…except…finally错误处理机制
相比返回错误代码,这是一种更为常见的错误处理方法
try:可能会出错的代码
except:可以有多个except来捕获不同的错误
finally:一定会被执行的语句,大多数情况可以不写
执行顺序:执行try中的语句片段,当出错是就跳转至except,最后一定会执行finally
调用栈
调用栈听起来很高端的样子,实际而言呢,咱们经常会遇到,就是在程序运行出错时,会返回的一系列信息,如下所示:
$ python3 err.py
Traceback (most recent call last):
File "err.py", line 11, in <module>
main()
File "err.py", line 9, in main
bar('0')
File "err.py", line 6, in bar
return foo(s) * 2
File "err.py", line 3, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
那么原理又是什么呢:如果错误没有被捕获,他就会一直往上抛,最终被python解释器捕获。下次报错的时候一定要仔细看看调用栈
记录错误:logging.exception(e)
抛出错误:raise(这个raise啊,我还没搞懂,廖老师也没详细讲,先占坑占坑)
调试
这一节,是我收获最多的,因为接触到了好多好多调试方法,终于可以把print抛弃啦,哈哈哈哈,方法一共有五种,就是下面这几个:
- print打印有问题的变量
- assert(断言)所有用print来查看的都可以使用断言
断言是什么,我还是不明白,不过至少开始了解了这个东西就是好事情嘛,先举个小例子,理解一下
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
- logging:称为调试界的最终武器,不会抛出错误,还会输出到文件中
import logging
logging.basicConfig(level = logging.INFO)
logging.info()
写上上面两句话,才能显示信息,第二句话的意思是:
允许使用level来指定信息的级别,共有:debug、info、warning、error几个级别。
- pdb(这玩意头一次听,好像是python的调试器)
使程序以单步运行,随时查看运行状态
python -m pdb err.py
几个pdb命令:
n 单步执行
1 查看代码
p+变量名 查看变量
q 退出
c 继续执行
- pdb.set_trace()
这个出现的原因绝壁是pdb单步调试速度太慢
使用方式:import pdb,然后在可能出错的地方防一个pdb.set_trace(),即可设置一个断点
单元测试
这块我是很蒙蔽的,之前看Cookbook的时候就是这样,可能缺少实践经验吧,主要熟悉unnittest模块就可以了
- 编写单元测试时,需编写一个测试类,然后从unittest.TestCase中继承,类中所有以test开头的方法都是测试方法,不以test开头的就不会被执行,如以下例子:
import unittest
from mydict import Dict
class TestDict(unittest.TestCase):
def test_init(self):
d = Dict(a=1, b='test')
self.assertEqual(d.a, 1)
self.assertEqual(d.b, 'test')
self.assertTrue(isinstance(d, dict))
def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEqual(d.key, 'value')
def test_attr(self):
d = Dict()
d.key = 'value'
self.assertTrue('key' in d)
self.assertEqual(d['key'], 'value')
def test_keyerror(self):
d = Dict()
with self.assertRaises(KeyError):
value = d['empty']
def test_attrerror(self):
d = Dict()
with self.assertRaises(AttributeError):
value = d.empty
- 有两种方式可以运行单元测试
- 当做普通脚本执行
- python3 -m unittest 文件名
- setUp和tearDown,是什么鬼东西啊
文档测试
这块持续蒙蔽,囧……
doctest模块可以直接提取注释重的代码并进行测试
if __name__ == '__main__':
import doctest
doc.testmod()
当模块正常导入时,不会被执行,只有在直接运行时才会执行doctest