作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
异常概述
在程序运行过程中,经常会遇到各种各样的错误,这些错误统称为 “异常”。这些异常有的是由于开发者一时疏忽将关键字敲错导致的,这类错误多数产生的是 SyntaxError: invalid syntax(无效的语法),这将直接导致程序不能运行。这类异常是显式的,在开发阶段很容易被发现。还有一类是隐式的,通常和使用者的操作有关。
Python 中常见的异常如下表所示:
异常 | 描述 |
---|---|
NameError | 尝试访问一个没有声明的变量引发的错误 |
IndexError | 索引超出序列范围引发的错误 |
IndentationError | 缩进错误 |
ValueError | 传入的值错误 |
KeyError | 请求一个不存在的字典关键字引发的错误 |
IOError | 输入输出错误(如要读取的文件不存在) |
ImportError | 当 import 语句无法找到模块或 from 无法在模块中找到相应的名称时引发的错误 |
AttributeError | 尝试访问未知的对象属性引发的错误 |
TypeError | 类型不合适引发的错误 |
MemoryError | 内存不足 |
ZeroDivisionError | 除数为 0 引发的错误 |
异常处理语句
在程序开发时,有些错误并不是每次运行都会出现的。这时就需要在开发程序时对可以出现异常的情况进行处理。在 Python 中,提供了 try…except 语句捕获并处理异常。在使用时,把可能产生异常的代码放在 try 语句块中,把处理结果放在 except 语句块中,这样,当 try 语句块中的代码出现错误,就会执行 except 语句块中的代码,如果 try 语句块中的代码没有错误,那么 except 语句块将不执行。
示例:
def division():
'''
功能:分苹果
:return: 无
'''
print("\n==================== 分苹果了 ====================\n")
apple = int(input("请输入苹果的个数: "))
children = int(input("请输入小朋友的个数: "))
result = apple // children
remain = apple - result * children
if remain > 0:
print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个,剩余", remain, "个")
else:
print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个")
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了 ~_~ 小朋友的个数不能为 0 !")
except ValueError as e:
print("输入错误: ", e)
多次运行示例的结果如下所示:
==================== 分苹果了 ====================
请输入苹果的个数: asda
输入错误: invalid literal for int() with base 10: 'asda'
==================== 分苹果了 ====================
请输入苹果的个数: 12
请输入小朋友的个数: 0
出错了 ~_~ 小朋友的个数不能为 0 !
==================== 分苹果了 ====================
请输入苹果的个数: 12
请输入小朋友的个数: 5
12 个苹果,评价分给 5 个小朋友,每人分 2 个,剩余 2 个
完整的异常处理语句应该包含 else 和 finally 代码块。else 代码块在程序没有抛出异常时执行,而 finally 代码块无论是否出现异常都会被执行。
示例:
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了 ~_~ 小朋友的个数不能为 0 !")
except ValueError as e:
print("输入错误: ", e)
else:
print("分苹果顺利完成!")
finally:
print("进行了一次分苹果操作!")
如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用 raise 语句在函数或方法中抛出异常。在应用 raise 抛出异常时,要尽量选择合理的异常对象,而不应该抛出一个与实际内容不相关的异常。
示例:
def division():
'''
功能:分苹果
:return: 无
'''
print("\n==================== 分苹果了 ====================\n")
apple = int(input("请输入苹果的个数: "))
children = int(input("请输入小朋友的个数: "))
if apple < children:
raise ValueError("苹果太少了,不够分!")
result = apple // children
remain = apple - result * children
if remain > 0:
print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个,剩余", remain, "个")
else:
print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个")
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了 ~_~ 小朋友的个数不能为 0 !")
except ValueError as e:
print("输入错误: ", e)
else:
print("分苹果顺利完成!")
finally:
print("进行了一次分苹果操作!")
上述例子的运行结果为:
==================== 分苹果了 ====================
请输入苹果的个数: 3
请输入小朋友的个数: 4
输入错误: 苹果太少了,不够分!
进行了一次分苹果操作!
程序调试
在程序开发过程中,免不了会出现一些错误,有语法方面的,也有逻辑方面的。语法方面的错误比较容易检测,因为程序会直接停止,并且给出错误提示。逻辑错误就不太容易发现了。因为程序可能会一直执行下去,但结果是错误的。所以作为一名程序员,掌握一定的程序调试方法,可以说是一项必备技能。
在程序开发过程中,除了使用系统自带的调试工具进行调试外,还可以在代码中通过 print() 函数把可能出现问题的变量输出进行查看。这种命令会产生很多垃圾信息,所以调试之后还需要将其删除,比较麻烦。除此之外,Python 还提提供了另外的方法 - 使用 assert 语句调试程序。assert 的中文意思是断言,它一般用于对程序某个时刻必须满足的条件进行验证。
示例:
def division():
'''
功能:分苹果
:return: 无
'''
print("\n==================== 分苹果了 ====================\n")
apple = int(input("请输入苹果的个数: "))
children = int(input("请输入小朋友的个数: "))
assert apple > children, "苹果不够分!"
result = apple // children
remain = apple - result * children
if remain > 0:
print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个,剩余", remain, "个")
else:
print(apple, "个苹果,评价分给", children, "个小朋友,每人分", result, "个")
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了 ~_~ 小朋友的个数不能为 0 !")
except ValueError as e:
print("输入错误: ", e)
else:
print("分苹果顺利完成!")
finally:
print("进行了一次分苹果操作!")
触发断言:
==================== 分苹果了 ====================
请输入苹果的个数: 5
请输入小朋友的个数: 6
进行了一次分苹果操作!
Traceback (most recent call last):
File "D:/Python/Demo/main.py", line 21, in <module>
division()
File "D:/Python/Demo/main.py", line 10, in division
assert apple > children, "苹果不够分!"
AssertionError: 苹果不够分!
通常情况下,assert 语句可以和异常处理语句结合使用。
try:
division()
except AssertionError as e:
print("\n输入有误:", e)
这样再执行程序时就不会直接抛出异常了。
注意:assert 语句只在调式阶段有效,我们可以通过在执行 Python 命令时加入 -O(大写)参数来关闭 assert 语句。