程序员每天遇到bug就像喝水吃饭一样平常,关键在于怎么高效而不失优雅的面对这些bug!
常见的异常BUG
- AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x
- IOError 输入/输出异常;基本上是无法打开文件
- ImportError 无法引入模块或包;基本上是路径问题或名称错误
- IndentationError 语法错误(的子类) ;代码没有正确对齐
- IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
- KeyError 试图访问字典里不存在的键
- NameError 尝试访问一个没有申明的变量
- SyntaxError Python代码非法,代码不能编译
- TypeError 传入对象类型与要求的不符合
- UnboundLocalError 试图访问一个还未被设置的局部变量
- ValueError 传入一个调用者不期望的值,即使值的类型是正确的
为了提高程序运行的稳健性,几乎所有语言都提供了 try……except……用法,他们能够确保程序能够跳过异常代码片段继续执行下去。
try:
<语句> #运行别的代码
except <异常类型>:
<语句> #如果在try部份引发了'name'异常
except <异常类型> as <数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
所以,你还在只使用 try……except 吗?
主动触发报错和异常是程序员大佬的装X护体方法之一!
本文主要介绍 Python 中的两个异常相关的关键字:assert 和 raise,
前者用于断言发现潜在异常,后者用于触发报错,实际上二者功能有很大相近之处。
assert:断言
assert 一般用于函数和类的内部,在执行具体逻辑前首先对输入参数和程序执行状态进行一定的检查和预判,仅当执行状态满足时才继续执行后续的逻辑,否则断言条件不满足,引发后续的提示。在表达式条件为 false 的时候触发异常。
assert 关键字基本用法为:
assert "条件判断", "条件不满足时输出的提示信息"
语法格式如下:
assert expression
等价于:
if not expression:
raise AssertionError
assert True # 条件为 true 正常执行
assert False # 条件为 false 触发异
例如,设计一个两数相除的函数,那么应当在执行相除前检查:
- 两个输入参数是否为数值型
- 除数是否不为0
这一条件判断可用assert完成,并在条件不满足时优雅的提示报错:
def div(x, y):
assert isinstance(x, (float, int)) and isinstance(y, (float, int)), \
"param `x` and `y` expected to be 'int' or 'float' type"
assert y != 0, "param `y` should not to be exactly `0`"
return x/y
div(1, "2")
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-206-579e0bede4d8> in <module>
----> 1 div(1, "2")
<ipython-input-205-258ec937e818> in div(x, y)
1 def div(x, y):
2 assert isinstance(x, (float, int)) and isinstance(y, (float, int)), \
----> 3 "param `x` and `y` expected to be 'int' or 'float' type"
4 assert y != 0, "param `y` should not to be exactly `0`"
5 return x/y
AssertionError: param `x` and `y` expected to be 'int' or 'float' type
(由于输入参数y是字符串类型,断言失败,引发断言错误)
由于输入参数y是字符串类型,断言失败,引发断言错误
assert 的最大意义:及时发现程序中未按预期状态执行的错误。
这在多人协作 coding 过程中,比 except 更能提供丰富的报错信息。
raise:触发异常
raise关键字基本语法为:
raise 异常类名称(描述信息)
例如,仍以实现上述 div 函数功能为例,以 raise 关键字执行同样的断言功能,则可如下实现:
def div(x, y):
if not isinstance(x, (float, int)) or not isinstance(y, (float, int)):
raise TypeError("param `x` and `y` expected to be 'int' or 'float' type")
if y == 0:
raise ZeroDivisionError("param `y` should not to be exactly `0`")
return x/y
div(1, 0)
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-213-4267cdef819f> in <module>
----> 1 div(1, 0)
<ipython-input-212-dce337c4d91a> in div(x, y)
3 raise TypeError("param `x` and `y` expected to be 'int' or 'float' type")
4 if y == 0:
----> 5 raise ZeroDivisionError("param `y` should not to be exactly `0`")
6 return x/y
ZeroDivisionError: param `y` should not to be exactly `0`
(由于除数为0,raise关键字触发异常)
raise 关键字与 assert 是有相通之处的。但raise 则只用于手动触发异常,某种程度上,raise 的灵活性要比 assert 低,且一般触发的是 Python 内置异常类型。
当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常。一旦执行了raise语句,raise后面的语句将不能执行。
raise <instance>
raise <class>
raise IndexError #Class(instance created)
raise IndexError() #Instance(created in statement)12

本文探讨了Python中的异常处理,重点介绍了assert断言和raise触发异常的使用。assert用于在代码执行前检查条件,如果条件不满足则抛出异常,有助于及时发现错误。而raise语句允许程序员手动触发异常,更适用于特定错误情况的处理。通过这两个关键字,开发者可以提升程序的稳健性和错误反馈的准确性。
1053

被折叠的 条评论
为什么被折叠?



