目录
异常
异常演示
异常类型
异常
什么是异常?
语法是正确的,但在运行它的时候,也有可能发生错误,这种运行期检测到的错误被称为异常。
为什么要对异常进行处理?
当我们预知当代码运行期间可能发生的错误,就可以在代码中对可能发生的错误进行处理。比如,代码中要求用户输入一个数字作为一个公式的分母,但用户输入了一个0或者输入了一个字母,就会导致异常发生。对于这种可预见的异常进行的处理就叫异常处理。
当我们认为某些代码可能会出错时,就可以用try
来运行这段代码
- 如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即
except
语句块,执行完except
后,如果有finally
语句块,则执行finally
语句块。如果执行没有出错,会绕过所有except语句块。 - 有一个可选的 else 子句,必须放在所有的 except 子句之后。else 子句将在 try 子句没有发生任何异常的时候执行。
- finally 语句无论是否发生异常都将执行最后的代码。
- 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中,直到被python解释器捕获。(也就是说异常处理并不仅仅处理那些直接发生在 try 子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。)
异常演示
下边这个代码
try:
print('try...\n')
a = int(input())
r = 100 / a
print('result:', r)
except ValueError as e:
print('ValueError:',e)
else:
print('no error!')
finally:
print('finally...')
print('END')
当输入12时,没有异常,执行了else语句和finally语句。
当输入一个字母的时候(比如输入r),则触发了异常,跳过else语句,执行finally语句。
此外,一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组。
except (RuntimeError, TypeError, NameError):
pass
异常类型
所有的错误类型都继承自BaseException
,所以在使用except
时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
除了这些异常,用户还可以自定义一些异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。
记录和抛出错误
如果对异常不做处理只做记录的话,python内置的logging
模块可以非常容易地记录错误信息,程序打印完错误信息后会继续执行,并正常退出。
用raise
语句抛出一个错误的实例。
语法:raise <Error_Type>
有时候,一个函数如果捕获到一种错误,但是不知道如何处理的话,可以将这个错误抛出,也就是抛给上级函数处理。
比如;
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise
bar()
捕获错误目的只是记录一下,便于后续追踪。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。