文章目录
- 错误和异常
- 程序错误
- 异常处理
- 断言处理
- 程序调试
错误和异常
程序错误
程序的错误
python程序中错误通常分为3种类型,即语法错误、运行错误和逻辑错误。
- 语法错误:源代码中的拼写语法错误,这些错误导致Python编译器无法把Python源代码转换为字节码,也称编译错误。包含语法错误时,编译器显示SyntaxError错误信息。
- 运行错误:python程序的运行时错误是在解释执行过程中产生的错误,例如程序没有导入random模块,解释器将在运行时抛出NameError错误信息。
- 逻辑错误:Python程序的逻辑错误时程序可以执行,但是执行结果不正确。对于逻辑错误,解释器无能为力,需要用户自己调试判断。
异常处理
python语言采取结构化的异常处理机制。在程序运行过程中,如果产生错误,将抛出异常;通过try语句来定义代码块,以运行可能抛出的异常的代码,通过except语句可以捕获特点的异常并执行相应处理,通过finally语句可以保证即使产生异常(处理失败),也可以在事后清理资源。
内置异常类
异常
在程序运行时,如果出现错误,Python解释器会创建一个异常对象,并抛出给系统运行时。即程序终止正常执行流程,转而执行异常处理流程。
在某种特殊条件下,代码中也可以创建一个异常对象,并通过raise语句抛出给系统运行时。
异常对象是异常类的对象实例。Python异常类均派生于BaseException。
引发异常
大部分由程序错误而产生的错误和异常一般由Python虚拟机自动抛出。另外在程序中如果判断某种错误情况,可以创建相应异常类的对象,并通过raise语句抛出。
# Python虚拟机自动抛出异常
1 / 0# ZeroDivisionError: division by zero
# 通过raise语句抛出异常示例
a = -1
if a < 0: raise ValueError("数值不能为负数")# ValueError: 数值不能为负数
使用try…except…else…finally语句捕获异常
异常处理
自定义异常类
虽然Python库中提供了许多异常,但在应用程序开发过程中,有时候需要定义特定于应用程序的异常类,表示应用程序的一些错误类型。
自定义异常类一般继承与Exception或其子类。自定义异常类的名称一般以Error或Exception为后缀
class NumberError(Exception): # 自定义异常类继承于Exception
def __init__(self, data):
Exception.__init__(self, data)
self.data = data
def __str__(self): # 重载__str__()方法
return self.data + ':非法数值(<0)'
def total(data):
total = 0
for i in data:
if i < 0:raise NumberError(str(i))
total += i
return total
data1 = (44, 78, 90, 80, 55)
data2 = (44, 78, 90, -80, 55)
print(total(data1))
# 347
print(total(data2))
# NumberError: -80:非法数值(<0)
断言处理
用户在编写程序时,在调试阶段往往需要判断代码执行过程中变量的值等信息(例如对象是否为空,数值是否为0等)
用户可以使用print()函数打印输出结果,也可以通过断点跟踪调试查看变量,但使用断言更加灵活高效。
一般用于下列情况:
- 前置条件断言:代码执行之前必须具备的特性
- 后置条件断言:代码执行之后必须具备的特性
- 前后不变断言:代码执行前后不能变化的特性
断言主要功能是帮助程序员调试程序,以保证程序运行的正确性,断言一般在开发调试阶段使用,即在调试模式时断言有效,在优化模式运行时自动忽略断言。
assert语句和AssertionError类
使用关键字assert可以声明断言
assert<布尔表达式> # 简单形式
assert<布尔表达式>, <字符串表达式> # 带参数的形式
-
<字符串表达式>是断言失败时输出的失败消息
-
如果断言成功则不报错,断言失败则导致AssertionError
a = 5
assert a == 10
#output:
#AssertionError:
a = 5
assert a == 10, "a的值不等于10"
#output:
#AssertionError: a的值不等于10
Python解释器有两种运行模式,即调试模式和优化模式。通常为调试模式,内置只读变量__debug__
为True;当选项-O运行时(即python.exe -O)为优化模式,此时内置只读变量__debug__
为False。故两种形式的assert语句相当于:
if __debug__:
if not testexpression: raise AssertionError
if __debug__:
if not testexpression: raise AssertionError(data)
程序调试
在程序实际运行之前,查找和修正其错误的过程称为调试(debugging)。
测试模块
1.安装pytest或ipytest(用于jupyter notebook)
pip install pytest
2.pytest是Python中非常流行的测试框架之一,它使得编写和运行测试变得非常简单。
3.简单DEMO(ipytest)
导入ipytest库,ipytest.autoconfig() 是 ipytest 模块的一个函数,用于自动配置 ipytest 以在 Jupyter Notebook 中运行。
import ipytest ipytest.autoconfig()
> 首先编写了一个过滤参数列表中能被5整除的函数
```python
def get_divisible_by_five(numbers):
"""Returns a list of numbers which are divisible by five in the list got as an argument"""
result = []
for num in numbers:
if not num % 5:
result.append(num)
return result
编写一个测试用例测试get_divisible_by_five函数能否正常工作
%%ipytest
#%%ipytest是一个Jupyter Notebook的魔法命令,它表明这个cell中的代码应该由ipytest模块来运行。
def test_get_divisible_by_five():#Python解释器或自动识别test_开头的函数作为测试
assert get_divisible_by_five([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) == [5, 10]
如果测试成功
> 如果测试失败