Python 异常处理

异常处理

在程序的开发过程中,我们要尽量的考虑更多情况,可能会出现的问题,提前对这些问题进行处理。防止程序运行的过程中出现异常而奔溃。


错误代码

在一些比较底层的语言,比如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

这种处理机制,在代码逻辑简单的时候,还能使用,一旦代码逻辑稍微复杂,嵌套的层级太多,就会非常麻烦。


try expect

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
Python 教程 Python 入门 Python 时间 Python JSON