【廖雪峰Python学习笔记】错误、调试、测试
文章目录
- 错误处理
- 调试
- 单元测试unitcase
- 文档测试
错误类型
- 程序编写问题bug – 字符类型错误等
- 用户输入错误 – 输入不符合规定的字符串
- 异常,程序运行时无法预测 – 磁盘满了,无法写
错误处理
错误处理机制:try…except…finally…
try
运行可能会出错的代码,若出错则后续代码不再运行try
中存在错误代码时,执行except
语句块抛出异常finally
可有可无,不论是否异常,最后都会执行- 所有错误类型均继承自
BaseException
- 不同
except
可以对不同错误类型进行处理 except
可以捕获自身及子类的错误except
可以跨越多层调用
try:print('try...')test_int = 10 / int('a') # 除法运算错误print('result = ', test_int) # 由于上一行代码错误,try的后续代码不再运行
except ZeroDivisionError as e: print('except: ', e)
except ValueError as e:print('ValueError:', e)
else:print('no error was found!')
finally:print('finally...')
print('END')
调用栈:出错时,须分析错误的调用栈信息,以定位错误的位置
Traceback (most recent call last):…………
logging
模块可以记录错误信息,且程序可继续执行
import logging
def foo(s):return 10 / int(s)
def bar(s):return foo(s) * 2
def main():try:bar('0')except Exception as e:logging.exception(e)
main()
输出结果:
ERROR:root:division by zero
Traceback (most recent call last):File "/Pratice/DEMO.py", line 8, in mainbar('0')File "/Pratice/DEMO.py", line 5, in barreturn foo(s) * 2File "/Pratice/DEMO.py", line 3, in fooreturn 10 / int(s)
ZeroDivisionError: division by zero
raise
抛出一个错误的实例
def foo(s):n = int(s)if n==0:raise ValueError('invalid value: %s' % s)return 10 / ndef bar():try:foo('0')except ValueError as e:print('ValueError!')raisebar()
输出结果:
Traceback (most recent call last):
ValueError!File "/Pratice/DEMO1.py", line 14, in <module>bar()File "/Pratice/DEMO1.py", line 9, in barfoo('0')File "/Pratice/DEMO1.py", line 4, in fooraise ValueError('invalid value: %s' % s)
ValueError: invalid value: 0
调试
使用print()调试,简单粗暴,但是调试过后需要删除调试代码
assert()
断言
def foo(s):n = int(s)assert n != 0, 'n is zero' # 若‘n != 0’不成立,则抛出AssertionErrorreturn 10/sdef main():foo('0')
main()
输出结果:
Traceback (most recent call last):File "/Pratice/DEMO2.py", line 8, in <module>main()File "/Pratice/DEMO2.py", line 7, in mainfoo('0')File "/Pratice/DEMO2.py", line 3, in fooassert n != 0, 'n is zero'
AssertionError: n is zero
tips:python -O DEMO2.py 可以将DEMO2.py中的assert当成pass来看
2. logging()
记录
输出文件而不是抛出错误
可指定记录信息的级别
通过简单配置,一条语句可同时输出到不同地方
import logging
# 指定记录信息的级别 debug->info->warning->error
logging.basicConfig(level=logging.INFO) s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
输出结果:
INFO:root:n = 0
Traceback (most recent call last):File "/Pratice/DEMO3.py", line 7, in <module>print(10 / n)
ZeroDivisionError: division by zero
pdb
调试器
让程序以单步方式运行,随时查看运行状态
➜ python -m pdb DEMO.py # 使用调试器查看单步运行状态
> /Users/amey/growingio/Pratice/DEMO.py(1)<module>()
-> import logging
(Pdb) l # l查看代码1 -> import logging2 logging.basicConfig(level=logging.INFO)3 4 s = '0'5 n = int(s)6 logging.info('n = %d' % n)7 print(10 / n)
[EOF]
(Pdb) n # n -> 单步执行代码
> /Users/amey/growingio/Pratice/DEMO.py(2)<module>()
-> logging.basicConfig(level=logging.INFO)
(Pdb) n # n -> 单步执行代码
> /Users/amey/growingio/Pratice/DEMO.py(4)<module>()
-> s = '0'
(Pdb) p s # p 变量名 -> 查看变量
> '0'
(Pdb) q # q -> 结束调试
单元测试unitcase
setUp()
和tearDown()
方法,在调用一个测试方法前后分别执行
[eg:连接关闭数据库]- 使用
python -m unittest test
可以批量运行多个单元测试
编写一个学生成绩单元测试
import unittestclass Student(object):def __init__(self, name ,score):self.name = nameself.score = scoredef get_grade(self):if(self.score > 100 or self.score < 0 or type(self.score) != int):raise ValueErrorelif(self.score < 60):return 'C'elif(self.score < 80):return 'B'else:return 'A'class TestStudent(unittest.TestCase):def test_80_to_100(self):s1 = Student('Amey', 100)s2 = Student('Jimmy', 80)self.assertEqual(s1.get_grade(),'A')self.assertEqual(s2.get_grade(),'A')def test_60_to_800(self):s1 = Student('Bart', 79)s2 = Student('Cindy', 60)self.assertEqual(s1.get_grade(),'B')self.assertEqual(s2.get_grade(),'B')def test_0_to_60(self):s1 = Student('Dan', 59)s2 = Student('Lisa', 0)self.assertEqual(s1.get_grade(),'C')self.assertEqual(s2.get_grade(),'C')def test_invaild(self):s1 = Student('Jan', 101)s2 = Student('King', -1)with self.assertRaises(ValueError):s1.get_grade()with self.assertRaises(ValueError):s2.get_grade()if __name__ == '__main__':unittest.main()
测试结果:
➜ python -m unittest DEMO4
....
----------------------------------------------------------------------
Ran 4 tests in 0.000sOK
文档测试
doctest模块:可提取注视中的代码并执行测试
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def fact(n):'''计算 1*2*3*...*n>>> fact(1)1>>> fact(-1)Traceback (most recent call last):File "/Pratice/demo.py", line 13, in <module>print(fact(-1))File "/Pratice/demo.py", line 7, in factraise ValueErrorValueError>>> fact(10)3628800'''if(n < 1):raise ValueErrorif(n == 1):return 1return n * fact(n-1)if __name__ == '__main__':import doctestdoctest.testmod()
【廖雪峰Python学习笔记】错误、调试、测试相关推荐
- 【廖雪峰Python学习笔记】字符串与编码
字符串与编码 三种字符编码 ASCII编码 :计算机由美国人发明,最早只有127个字符编码-- 大小写英文字母.数字和符号 Unicode:把中文.日文.韩文等所有语言统一到一套编码中,2-4byte ...
- 廖雪峰python学习笔记之高级特性
写在前面 寒假时本科舍友的一句话点醒梦中人-你的python基础还没弄明白吧!猛地一想好像确实如此,还停留在随插随用的程度,并且对于迭代器,函数式编程等等,没有深刻理解,所以项目做起来也是空中楼阁,所 ...
- 廖雪峰Python学习笔记1
Python基础 文章目录 一.基础语法规范 二.数据类型 三.字符串与编码 四.条件判断 五.循环 一.基础语法规范 1.用#作为代码注释 2.当语句以冒号:结尾时,缩进的语句视为到麻花,缩进**使 ...
- 【廖雪峰Python学习笔记】面向对象高级编程
文章目录 为实例和类绑定属性和方法 \_\_slots__限制当前class实例,对子类不管用 @property装饰器,将`getter`方法变成属性 多重继承 -- 一个子类可同时获得多个父类的所 ...
- 【廖雪峰Python学习笔记】面向对象编程OOP
面向对象编程 OOP:Object Oriented Programming 程序的基本单元:对象 [ = 数据 + 操作数据的函数] [属性 + 方法] 三大特点:数据封装.继承和多态 OPP中的计 ...
- 【廖雪峰Python学习笔记】函数式编程
Functional Programming 高阶函数 返回函数 匿名函数 装饰器 偏函数 高阶函数 面向过程的程序设计: 把大段代码拆成函数,通过一层层函数调用,可将复杂任务分解成若干简单的任务 函 ...
- 【廖雪峰Python学习笔记】list tuple dict set
列表 元组 字典 集合 创建 l = [1, 'a', [1, 3], True] t = (1, ) d = {'key' : 'value'} s = set([1, 2, 4, 2, 1]) 索 ...
- 廖雪峰Python学习笔记——类和实例
Class MyList(list): __metaclass__ = ListMetaclass #它表示在创建MyList这个类时,必须通过 ListMetaclass这个元类的LIstMetac ...
- 廖雪峰python学习笔记——函数式编程
一个简单粗暴的内置函数: reduce()和map()的区别: map()是将函数依次作用到每个参数上,而reduce()相当于是迭代,而且每次都必须是两个参数. 用reduce()和map完成str ...
最新文章
- Glide和Govendor安装和使用
- 微信小程序上传图片到服务器不显示,微信小程序上传图片到服务器wx.uploadFile...
- apache的日志级别和设置
- Python: How to import other Python files
- 计算机单招六百分好考吗,单招分数线一般多少 单招考过的几率有多少
- 计算机网络信息安全理论与实践教程-蒋建春
- java.nio.DirectByteBuffer管理堆外内存
- python系统下载-python
- 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号
- VB.NET 强制删除文件
- 5G移动通信发展历程
- PostgreSQL导入导出CSV
- 计算机网络知识自问自答,2020计算机网络学习心得体会.doc
- 【Python】基础语法之一:变量、字符串、数、注释
- python空行分隔代码_python空行分隔
- 常见字读音(粤语)---(5)
- X99主板2011-3接口E5 CPU一览表
- execution使用
- Unity五子棋游戏设计 和简单AI实现(1)
- 极简html4网页布局,浅淡极简的网页设计:少即多
热门文章
- 【iOS】通讯录分组方式展示数据
- iOS 生成带 logo 的二维码,区域截屏保存至相册(小功能二连发 (一))
- 图的遍历——DFS(邻接矩阵)
- cnpm install -g generator-gulp-webapp yo gulp-webapp test-gulp-webapp
- 【独家】深入浅出话AI:定义和主要研究方法
- Ubuntu下ssh免password登录安装
- php跨域共享session
- 怎么处理404 错误页面 、处理404页面、asp.net 处理404页面
- 用友云平台,真正的云原生架构,加速云应用落地
- Centos7 下 配置 rsync 以及 rsync+inotify 实时同步