Python的异常问题(Python Exception)
作者:子黄求知若渴
这篇文章主要介绍了Python的异常问题(Python Exception),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
异常 Exception
错误
- 在编写代码时能够避免的
- 语法错误:未按照代码限制进行编写,或者手误拼错了变量名等
- 逻辑错误:思维方向出现了问题,算法不正确等。
异常
- 编写代码阶段无法避免的,与运行时环境相关的错误。例如打开的文件不存在,网络中断等。
- 异常是可追溯的,Python中使用Tranceback来追溯异常。
Python中的Exception
- Python中提供了一系列异常类和try语句块来捕获和处理异常。
- 如果程序中触发了异常,当前函数未捕获则会向外抛出抛给调用者,直到被捕获或者抛到Python解释器,解释器停止当前线程,如若是主线程,也结束当前进程。
- 当程序出现异常时,将会导致后续的进行不可控,所以异常未处理终止线程的操作是很有必要的。
- 异常出现导致的后果十分严重,需要在抛到解释器前进行处理。
raise
- 使用raise Exception来显式抛出异常。
- raise会抛出一个所跟的异常类实例,如果跟的是一个类,则无参地初始化后抛出。
- 在except中或者finally中可以使用不跟对象的raise,会抛出最近触发的一个异常。
raise Exception # 使用无参初始化 raise Exception('Exception', 200) #带参初始化 try: raise Exception() except: raise # 抛出上面的异常实例
try语句块
语句 | 作用 |
---|---|
try | 在try后except前的语句将会由except来捕获 |
except | 语句后跟一个异常类(继承自BaseException或其子类),该except会捕捉该类或其子孙类实例。如果未捕获到且后续还有except语句则会由后续语句继续捕获,如果到最后一个except语句仍未被捕获,则抛出到调用者。可以在类后跟 as e ,在as后跟一个变量会将捕获到的异常类实例赋给变量。 |
finally | 在finally语句中的语句不管是否发生异常都会被执行 |
else | 如果没有发生异常,执行else中的语句 |
- try语句后必须有exception或finally语句二者其一。
- 在exception或者finally中如果有return或者break语句,执行语句时会忽视该异常。
try: 1 / 0 # 将会触发0除异常 ZeroDivisionError except SystemExit as e: # 不是ZeroDivisionError异常的祖先类,捕获不到 print('SystemExit', e) except ZeroDivisionError as e:# 捕获ZeroDivisionError异常 print('ZeroDivisionError', e) else: print('else') # 有异常,else语句不执行 finally: print('fianlly') >>>ZeroDivisionError division by zero >>>finally try: x = 1 # 不产生异常 except SystemExit as e: print('SystemExit', e) except ZeroDivisionError as e: print('ZeroDivisionError', e) else: print('else') # 没有异常,else语句被执行 finally: print('fianlly') # finally中的语句依旧被执行 >>>else >>>finally
捕获策略
- 如果异常不处理,则会向上一层,即调用者抛出,直到解释器。
- 所以可以在发生处到解释器途中进行捕获处理,所以在哪个位置进行处理也是一个问题。
立即捕获
在异常发生处直接捕获进行处理。
- 发生后直接就处理了,不向外抛出,消耗最小,最高效。
- 用户不需要管是否发生了异常,只要处理了即可。
- 可能不是调用者想要的结果,有点过于自作主张了。
def get_int(data): """ 转换一个值为int类型 """ try: return int(data) except: return 0
发生异常后直接返回一个固定的值,而不向外抛出。
调用者无需处理该异常,有时返回的结果不符合预期。
边界捕获
封装产生边界
- 在设计模块或者其他服务的时候,发生异常应该交由调用者来处理。如果自行处理,调用者无法察觉并处理该异常
- 例如内建函数open,文件不存在会抛出FileNotFoundError异常,把处理权交由用户。用户不处理则线程退出。
类继承树
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
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。