本博文源于python基础,主要探讨python的错误、异常合程序调试。包含:语法错误、异常处理、手工抛出异常、assert语句、自定义异常类、pdb调式程序、测试程序。
语法错误
拼写错误
比如print硬生生拼成printtt
脚本程序不符合python的语法规范
比如少括号、冒号等符号
缩进错误
没有按照标准的四个空格缩进。一般很难会产生这种错误。
异常的处理
异常处理的基本语法
完整格式
try:
<语句块>
except <异常名1>:
<语句块>
except <异常名2>:
<语句块>
....
else:
<语句块>
finally:
<语句块>
这块代码格式的语句是这样子的分为有无异常,
- 如果有异常,执行异常所在的except语句,不执行else,然后执行finally
- 如果无异常,执行else,执行finally
其他形式的捕获异常格式
try:
<语句块>
except <异常名1>:
<语句块>
try:
<语句块>
except <异常名1>:
<语句块>
finally:
<语句块>
例子:捕获获取列表索引是否存在的异常,观察有什么发现
def testTry(index, flag=False):
stulst = ["John", "Jenny", "Tom"]
if flag:
try:
astu = stulst[index]
except IndexError:
print("IndexError")
return "Try Test Finished!"
else:
astu = stulst[index]
return "No Try Test Finished!"
print("Right parmas teting start....")
# 执行成功的代码
print(testTry(1, True))
# 不越界的代码
print(testTry(1, False))
# 索引不存在检测异常代码
print(testTry(4, True))
# 索引不存在不检测异常
print(testTry(4, False))
通过上面的代码执行会发现捕获异常的时候,如果捕获到那就程序处理异常,然后正确往下面走。如果没捕获到异常那就陷入奔溃的程序,这也是保证程序的健壮性。
python主要内置及其处理
常用的异常函数
异常名 | 描述 |
---|---|
AttributeError | 调用不存在的方法引发异常 |
EOFError | 遇到文件末尾引发的异常 |
ImportError | 导入模块出错引发的异常 |
IndexError | 列表越界引起的异常 |
IOError | I/O操作中的引发异常 |
KeyError | 使用字典不存在的关键字引发的异常 |
NameError | 使用不存在的变量名引发的异常 |
TabError | 语句块缩进不正确引发的异常 |
ValueError | 搜索列表中不存在的值引发的异常 |
ZeroDivisionError | 除数为0引发的异常 |
except语句主要有以下几种用法。
- except: 捕获所有异常
- except <异常名>:捕获指定异常
- except(异常名1,异常名2):捕获异常名1或者异常名2
- except<异常名> as <数据>:捕获指定异常及其附加得数据
- except(异常名1,异常名2) as <数据>:捕获异常名1或者异常名2及异常的附加数据
手工抛出异常
用raise手工抛出异常
raise 异常名
raise 异常名,附加数据
raise 类名
例子:代码执行遇到2抛出NameError异常
def testRaise():
for i in range(5):
if i==2:
raise NameError
print(i)
print('end...')
testRaise()
效果
例子:捕获异常,继续运行
def testRaise():
for i in range(5):
try:
if i==2:
raise NameError
except NameError:
print('Raise a NameError')
print(i)
print('end...')
testRaise()
assert语句
语句格式
assert <条件测试>,<异常附加的数据>
assert语句是简化的raise语句,它引发异常的前提是其后面的条件测试为假
assert使用场景
assert语句一般用于在程序开发时测试代码的有效性。比如某个变量的值必须在一定范围内,而运行时得到的值不符号要求,则引发该异常,对开发者予以提示。所以一般在程序中不去捕获这个异常,而是让它中断程序。因为程序中已经出现问题,没有必要继续运行下去。
例子:抛出程序执行到2的assert异常
def testAssert():
for i in range(3):
try:
assert i<2
except AssertionError:
print('Raise a AssertionError!')
print(i)
print('end...')
testAssert()
自定义异常类
在python中定义异常类不用从基础完全自己定义,只要通过继承Exception类来创建自己的异常类。异常类的定义和其他类没有区别,最简单的自定义异常类甚至可以只继承Exception类,类体为pass:
例子:程序自定义异常类,并用代码将其引发
class RangeError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return self.value
raise RangeError('Range Error!')
用pdb调试程序
调试语句块函数
格式
run(statement[, globals[, locals]])
- statement 要调试的语句块,以字符串的形式表示
- global 可选参数,设置statement运行的全局环境变量
- locals 可选参数,设置statement运行的局部环境变量
pdb交互命令表
完整命令 | 简写命令 | 描 述 |
---|---|---|
args | a | 打印当前函数的参数 |
clear | cl | 清除断点 |
break | b | 设置断点 |
condition | 无 | 设置条件断点 |
continue | c或者cont | 继续运行,直到遇到断点或者程序结束 |
disable | 无 | 禁用断点 |
enable | 无 | 启用断点 |
help | 无 | 查看pdb帮助 |
ignore | 无 | 忽略断点 |
jump | j | 跳转到指定行数运行 |
list | l | 列出程序清单 |
next | n | 执行下条语句,遇到函数不进入其内部 |
p | p | 打印变量值,也可以用print |
quit | q | 退出pdb |
return | r | 一直运行到函数返回 |
tbreak | 无 | 设置临时断点,断点只中断一次 |
step | s | 执行下一条语句,遇到函数进入其内部 |
where | w | 查看所在的位置 |
! | 无 | 在pdb中执行语句 |
调试函数
pdb模块中的调试函数应当调用模块中的runcall函数,其参数原型为:
runcall(function [,argument,...])
- function 函数名
- argument 函数的参数
例子:用pdb测试执行0,1,2
import pdb
pdb.run("""
for i in range(3):
print(i)
""")
例子:使用pdb进行测试函数逐条执行
import pdb
def sumn(maxint):
s = 0
for i in range(maxint):
s+= i
return s
pdb.runcall(sumn,10)
print(sumn(10))
测试程序
用testmod函数
用testmod函数进行单元测试,就要将测试用例写入程序的docstring中
例子:自写if判断,用testmod进行测试
import pdb
def grade(sum):
"""
>>> grade(100)
'优秀'
>>> grade(80)
'良'
>>> grade(65)
'合格'
>>> grade(10)
'不合格'
"""
if sum>90:
return '优秀'
if sum>80:
return '良好'
if sum>60:
return '合格'
if sum<60:
return '不合格'
if __name__ == '__main':
import dectest
doctest.testmod()
同testfile测试
例子:自写if判断,用testfile进行测试
在myt.txt中输入
>>> from test import grade
>>> grade(20)
'不合格'
>>> grade(100)
'优秀'
>>> grade(65)
'合格'
在test.py中输入
import pdb
def grade(score):
if score > 90:
return '优秀'
if score > 80:
return '良好'
if score > 60:
return '合格'
if score < 60:
return '不合格'
if __name__ == '__main__':
import doctest
doctest.testfile('myt.txt')
测试效果
无异常