借鉴:
廖雪峰python教程《错误处理》
python3官方教程《Exception hierarchy》:
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
try
try:
#do something
except built-in exceptions class name as e:#捕获错误类名
#do something like: print(e), 会打印具体错误内容
finally:
#do something
Exception hierarchy
The class hierarchy for built-in exceptions is:
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
Note:try执行代码,可以跨越多层捕获底层错误。
例子:
函数main()调用bar(),bar()调用foo(),结果foo()出错了,这时,只要main()捕获到了,就可以处理:
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
try:
bar(‘0’)
except Exception as e:
print(‘Error:’, e)
finally:
print(‘finally…’)
也就是说,不需要在每个可能出错的“底层”去捕获错误,只要在合适的层次去捕获错误就可以了。
调用栈
如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。
解读错误信息是定位错误的关键。
出错的时候,一定要分析错误的“调用栈”信息,才能定位错误的位置。
如这个调用函数链:
# err.py:
def foo(s):
return 10 / int(s)
def bar(s):
return foo(s) * 2
def main():
bar('0')
main()
$ python3 err.py
Traceback (most recent call last):
File "err.py", line 11, in <module>
main()
File "err.py", line 9, in main
bar('0')
File "err.py", line 6, in bar
return foo(s) * 2
File "err.py", line 3, in foo
return 10 / int(s)
ZeroDivisionError: division by zero
记录错误
使用except Exception as e:
logging.exception(e)
如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
main()
print('END')
程序打印完错误信息后会继续执行,并正常退出。
抛出错误(可与try except并行使用,try except负责捕获并记录错误,便于后续追踪,而raise负责将错误信息向上层调用者抛,)
因为错误是class,捕获一个错误就是捕获到该class的一个实例。
Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。
只有在必要的时候才定义我们自己的错误类型。如果可以选择Python已有的内置的错误类型(比如ValueError,TypeError),尽量使用Python内置的错误类型。
定义我们自己的错误类型(class): 选择好继承关系,然后,用raise语句抛出一个错误的实例.
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()
ValueError! #except打印出的
#raise
Traceback (most recent call last):
File "D:/STUDY/job/part2_ML/NLP/cs224n/assignment/hw1/numpyTry1.py", line 23, in <module>
bar()
File "D:/STUDY/job/part2_ML/NLP/cs224n/assignment/hw1/numpyTry1.py", line 17, in bar
foo('0')
File "D:/STUDY/job/part2_ML/NLP/cs224n/assignment/hw1/numpyTry1.py", line 11, in foo
raise ValueError('invalid value: %s' % s)
ValueError: invalid value: 0
Process finished with exit code 1
本文介绍了Python中的错误处理和异常机制,包括错误的层次结构、如何使用try-except-finally捕获和处理异常,以及如何通过logging模块记录错误信息。通过示例解析了错误调用栈和如何抛出及自定义错误。强调了正确层次的错误捕获和理解错误信息对定位问题的重要性。

被折叠的 条评论
为什么被折叠?



