在程序的开发过程中,我们要尽量的考虑更多情况,可能会出现的问题,提前对这些问题进行处理。防止程序运行的过程中出现异常而奔溃。
在一些比较底层的语言,比如C
,如果要捕获异常
的行为,我们需要自己事先判断,然后返回错误代码
。
def t(x):
if x != 1:
return 0 # 返回错误 | 代码 0 表示 x 错误
def c(x):
if t(x) == 0: # 捕获错误
print('Error')
else:
print(1)
>>> c(8)
'Error'
>>> c(1)
1
这种处理机制,在代码逻辑简单的时候,还能使用,一旦代码逻辑稍微复杂,嵌套的层级太多,就会非常麻烦。
Python
中内置了更高级的异常处理机制
,try expect
,大部分的现代高级语言都能够支持,有了这套机制,我们就能通过比较简洁的方式处理异常行为。
>>> try:
>>> n = 1 / 0 # 0 不能是被除数,否则会报错
>>> except ZeroDivisionError as e: # as 是别名,定义之后 ZeroDivisionError = e
>>> print(e) # e 错误信息
>>> finally:
>>> print('finally')
'division by zero'
'finally'
执行流程
try
... # 运行代码
except:
... # 运行失败时捕获,成功则跳过
finally:
... # 无论运行成功,或者失败,finally 都会被执行
错误的类型不指是一种,我们可以根据不同的类型,进行不同的捕获处理
。
>>> try:
>>> n = 1 / 0
>>> except ZeroDivisionError as e:
>>> pass
>>> try:
>>> n = 1 / 0
>>> except ArithmeticError as e:
>>> pass
>>> except Exception as e:
>>> pass
1/0
产生的错误,我们通过 ZeroDivisionError
可以捕获得到,通过ArithmeticError
或者Exception
也可以。except
可以通过捕获不同类型,定义多个。
错误的类型不仅不只有一种,而还是上下级的关系,每一种错误的类型都是一个类
,小类型的错误,是通过对大类型错误的继承。所以我们通过捕获BaseException
,就能捕获到任何错误。
错误关系
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
程序运行的过程中出现了错误,如果我们没有对错误进行捕获处理,Python的解释器就会终止运行,并且抛出错误
。我们自己也能通过raise
实现对错误的自定义抛出。
def f():
try:
...
...
...
except Exception as e:
raise e # 这个错误我们不知道怎么处理,抛给同事
# 同事调用的时候,把这个错误处理了
>>> try:
>>> f()
>>> except Exception as e:
>>> ...
>>> ...
因为错误的类型是通过对BaseException
类的继承,所以我们也可以通过继承的方式,实现一个自定义的错误类。
class Err(Exception):
def __init__(self):
print('err')
>>> raise Err()
err