Python 中错误一般分为两种:
print('hi) # 语法错误
res = 1/0 # 逻辑错误
int('s') # 逻辑错误
异常是程序在运行时发生错误而产生的信号。
print(hello) # 引发异常的错误
---------------------------------------------------------------------------
NameError Traceback (most recent call last) # 追溯信息
<ipython-input-1-1cd80308eb4c> in <module>()
----> 1 print(hello)
NameError: name 'hello' is not defined # 异常类、异常值
异常包括:
Traceback (most recent call last)
NameError
name ‘hello‘ is not defined
Python 解释器检测到错误,触发异常(程序员自己也可以触发如: raise)。程序员自己编写一段特定的代码(与程序逻辑无关),用来捕捉这个异常。
捕捉成功后进入另一个处理逻辑,其目的是使程序不奔溃,—— 这就是异常处理。
程序运行错误,触发异常,导致整个程序在错误处停止,后面的代码不会被执行。用户不会喜欢一款总是奔溃的程序。因此给程序提供一种强大的异常处理机制来增强程序的健壮性和容错性很有必要。
Python 为每一种异常定制了一种类型,一种异常标识一种错误。
类型 | 说明 |
---|---|
AttributeError | 试图访问一个对象不存在的属性,如:A.x,而 A 不存在 x 属性 |
IOError | 输入/输出异常,一般为无法打开文件 |
ImportError | 无法引入模块或包,一般为路径问题或名称错误 |
IndentationError | 语法错误的子类,一般为代码没有正确对齐 |
IndexError | 索引超出序列边界,如:x 只有三个元素,却试图访问 x[5] |
KeyError | 试图访问字典里不存在的键 |
KeyboardInterrupt | Ctrl+C 终止程序引发的,仅在终端有效 |
NameError | 使用一个未定义的变量 |
SyntaxError | 语法错误 |
TypeError | 传入对象类型与要求的不符合 |
UnboundLocalError | 试图访问一个还未被设置的局部变量,一般是有另一个同名的全局变量,导致你以为正在访问它 |
ValueError | 传入一个无效的参数,即使值的类型是正确的 |
Python 提供了一种特定的语法结构来进行异常处理。
try-except
语法结构:
try:
可能会出现错误的代码
except 异常类型: # 还可以写成 except 异常类型 as e (e 为异常值)
触发异常后执行的代码
示例:
try:
s = input('please input a num:')
s = int(s)
except ValueError as e:
print(e)
please input a num:sd
invalid literal for int() with base 10: 'sd' # 异常值
异常类只能捕捉特定的异常,即在进行异常处理之前,首先需要对异常类型进行判断。若异常类型与判断的类型不一致,则会导致处理失败。
try:
l = [1, 2, 3]
l[5]
except NameError as e:
print(e)
IndexError: list index out of range
上面程序中,指定的异常类型为 NameError
,而实际的异常类型为 IndexError
,捕捉失败。
多分支
异常处理还可以像 if 语句一样,可以多分支判断:
try:
l = [1, 2, 3]
l[5]
except NameError as e:
print(e)
except IndexError as e:
print(e)
list index out of range
万能异常
多分支固然可以进行多次判断,但是一旦遇到我们不知道会发生什么异常的时候,就显得有点捉襟见肘了。而且大量的多分支语句,会使得整个程序可读性很差。
Python 给我们提供了一种万能捕捉异常 Exception
,它可以捕捉任何异常,从而不用担心异常类型错误:
try:
l = [1, 2, 3]
l[5]
except Exception as e:
print(e)
list index out of range
多分支与万能异常结合使用
try:
l = [1, 2, 3]
l[5]
except NameError as e:
print(e)
except IndexError as e:
print(e)
except Exception as e:
print(e)
总结
Exception
即可。除了 try-except
语句外,还有另外一种异常处理语句 :try-else-finally
。
语法结构:
try:
可能会触发异常的代码块
else:
print('没有异常时执行的代码块')
finally:
print('无论是否有异常,都会执行该段代码,通常是清理工作')
示例:
try:
l = [1, 2, 3]
l[5]
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except Exception as e:
print(e)
else:
print('else 执行')
finally:
print('finally 执行')
list index out of range
finally 执行
程序出现错误时,会自动触发异常。也可以通过 raise 语句显示地主动触发异常,一旦执行了 raise 语句,raise 后面的语句将不会被执行。语句结构:raise 异常类()
。
s = 'ab'
try:
if type(s) == str:
raise ValueError('ValueError')
except Exception as e:
print(e)
ValueError
每种异常都是一个类,那么也可以自定义异常类。需要注意的是:自定义的异常需要继承 BaseException。
class DefineError(BaseException):
def __init__(self, msg):
self.msg = msg
try:
raise DefineError('自定义异常')
except Exception as e:
print(e)
---------------------------------------------------------------------------
DefineError Traceback (most recent call last)
<ipython-input-8-9f72e7503995> in <module>()
4
5 try:
----> 6 raise DefineError('自定义异常')
7 except Exception as e:
8 print(e)
DefineError: 自定义异常
断言 assert 与 if 条件语句类似,不过它更为简洁。
语法结构:
assert 条件 # 条件符合则继续执行,否则报错
示例:
n = 90
assert n > 85
print('良好')
良好
try...excepy 与 if 的区别
异常处理是附加给程序的一种处理逻辑,与主要工作没有关系。滥用会导致代码可读性差,那么在什么时候可以用呢?
当你遇到一些无法预知的错误时(如:爬取某个站点时爬取超时),就需要用到异常处理来避免程序奔溃。平常情况应该尽量避免少用,尽量减少程序语法以及逻辑性错误。
原文:https://www.cnblogs.com/midworld/p/10847317.html