600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Python 异常处理 详解

Python 异常处理 详解

时间:2023-01-15 16:36:44

相关推荐

Python 异常处理 详解

Python 异常处理 详解

1、错误和异常1.1 错误 `Error`1.2 异常 `Exception`1.3 总结2、产生异常3、捕获异常3.1 语法3.2 示例 13.3 示例 24、 异常类4.1 `Exception hierarchy`4.2 `BaseException`及子类4.3 `sys.exit()`示例 14.4 `sys.exit()`示例 24.5 `KeyboardInterrupt`示例4.6 `SyntaxError`示例4.7 自定义类示例5、多种捕获5.1 捕获规则5.2 示例 15.3 示例 26、其它子句介绍6.1 示例 16.2 示例 26.3 示例 36.4 示例 46.5 示例 56.6 示例 67、异常的传递7.1 示例 17.2 示例 28、`try`语句8.1 `try` 语法8.2 `try` 工作原理8.3 示例 18.4 示例 29、异常的捕获时机10、自定义异常类注意事项10.1 异常类写的有问题10.2 异常类传入参数10.3 异常类传入默认参数

1、错误和异常

1.1 错误Error

逻辑错误:算法写错了,例如加法写成了减法笔误:例如变量名写错了,语法错误函数或类使用错误:其实这也属于逻辑错误总之,错误是可以避免的

1.2 异常Exception

异常就是意外情况在没有出现上述错误的前提下,也就是说程序写的没有问题,但是在某些情况下,会出现一些意外,导致程序无法正常执行下去例如,访问一个网络文件,突然断网了,这就是个异常,是个意外的情况总之,异常是不可能避免的

1.3 总结

错误和异常:在高级编程语言中,一般都有错误和异常的概念,异常是可以捕获的,并被处理的,但是错误是不能被捕获的一个健壮的程序,尽可能的避免错误,尽可能的捕获、处理各种异常

2、产生异常

1 raise 语句显式的抛出异常

2 Python 解释器自己检测到异常并引发它

3 程序会在异常抛出的地方中断执行,如果不捕获,就会提前结束程序(其实是终止当前线程的执行)

def foo():print('before')print(1/0) # 捕获异常 print('after')foo()# ZeroDivisionError: division by zerodef foo():print('before')raise Exception('My Exception') # raise 主动抛出异常 print('after')foo()# Exception: My Exception

3、捕获异常

3.1 语法

try:待捕获异常的代码块except [异常类型]:异常的处理代码块

3.2 示例 1

此例执行到c = 1/0时产生异常并抛出,由于使用了try...except语句块则捕捉到了这个异常

异常生成位置之后语句块将不再执行,转而执行对应的except部分的语句

最后执行try...except语句块之外的语句

def foo():try:print('before')c = 1/0print('after')except:print('error')print('catch the exception')foo()print('====== end ======')

beforeerrorcatch the exception====== end ======

3.3 示例 2

def foo():try:print('before')print(1/0)print('after')except ArithmeticError: # 指定捕获的类型print('error')print('catch the exception')foo()print('====== end ======')

beforeerrorcatch the exception====== end ======

4、 异常类

4.1Exception 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+-- EncodingWarning+-- ResourceWarning

4.2BaseException及子类

BaseException:所有内建异常类的基类是BaseExceptionSystemExitsys.exit()函数引发的异常,异常不捕获处理,就直接交给Python解释器,解释器退出KeyboardInterrupt:对应的捕获用户中断行为Ctrl + CException及子类:

1、Exception是所有内建的、非系统退出的异常的基类,自定义异常类应该继承自它

2、SyntaxErrorPython将这种错误也归到异常类下面的Exception下的子类,但是这种错误是不可捕获的

3、ArithmeticError:所有算术计算引发的异常,其子类有除零异常等

4、LookupError:使用映射的键或序列的索引无效时引发的异常的基类:IndexError,KeyError

5、 自定义异常类:从Exception继承的类

4.3sys.exit()示例 1

import sysKeyboardInterruptprint('Before')sys.exit(1)print('SysExit')print('outer')

D:\PycharmProjects\pythonProject\08089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/08089/test6.pyBeforeProcess finished with exit code 1

4.4sys.exit()示例 2

import systry:sys.exit(1)except SystemExit:print('SysExit')print('outer')

D:\PycharmProjects\pythonProject\08089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/08089/test6.pySysExitouterProcess finished with exit code 0

4.5KeyboardInterrupt示例

try:import timewhile True:time.sleep(1)print('!!!')except KeyboardInterrupt:print('Ctrl + C')print('=== end ===')

PS D:\PycharmProjects\pythonProject\08089> python .\test8.py!!!!!!Ctrl + C=== end ===PS D:\PycharmProjects\pythonProject\08089>

4.6SyntaxError示例

语法错误直接报错,无法捕捉,解释器连执行都不会去做

try:0a = 5except SyntaxError: # 无法捕获print('after')

SyntaxError: invalid syntax

print('=' * 10)def 0a():print('begin')try:0a()except Exception as e:print(e, type(e))

D:\PycharmProjects\pythonProject\08089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/08089/test8.pyFile "D:/PycharmProjects/pythonProject/08089/test8.py", line 1def 0a():^SyntaxError: invalid syntaxProcess finished with exit code 1

4.7 自定义类示例

class MyException(Exception):passtry:raise MyExceptionexcept MyException: # 捕捉自定义异常print('Catch the exception')Out:Catch the exception

5、多种捕获

多种捕获:except可以指定捕获的类型,捕获多种异常。

5.1 捕获规则

1 捕获是从上到下依次比较,如果匹配,则执行匹配的except的语句块2 如果被一个except语句捕获,其它except语句就不会再次捕获了,谁在前谁捕获3 如果没有任何一个except语句捕获到这个异常,则该异常向外抛出4 捕获原则:从小到大,从具体到宽泛5 编写异常时:越具体的异常,越往上写;宽泛的,往下写;尽量不要压制异常

5.2 示例 1

import sysclass MyException(Exception):passtry:print('before')a = 1/0#raise MyException()#open('t')#sys.exit(1)except MyException:print('catch my exception')except ArithmeticError: # 可以捕获除零异常print('ari')except ZeroDivisionError: # 可以捕获除零异常print('zero')except MyException:print('catch my exception')except BaseException: # 可以捕获除零异常print('Base')except Exception: # 可以捕获除零异常print('exception')except:print('sysexit')

5.3 示例 2

class A:passtry: raise A()except:print('catch the exception')Out:catch the exception

6、其它子句介绍

as子句:被抛出的异常,应该时异常类的实例,可以使用as子句获得这个对象raise语句:raise后要求应该是BaseException类的子类或实例,如果是类,将被无参实例化;raise后什么都没有,表示抛出最近一个被激活的异常,如果没有被激活的异常,则抛出类型异常;raise是用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是ErrorException类的子类Python用异常对象(exception object)表示异常情况,遇到错误后,会引发异常如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止执行finally子句:最终,即最后一定要执行的,try...finally语句块中,不管是否发生了异常,都要执行finally的部分else子句:没有任何异常发生,则执行

6.1 示例 1

class MyException(Exception):def __init__(self, code, message):self.code = codeself.message = messagetry: raise MyException()raise 1/0# raiseexcept MyException as e:print('catch my exception')except Exception as e:print(e)print('=== end ===')Out:__init__() missing 2 required positional arguments: 'code' and 'message'=== end ===

6.2 示例 2

class MyException(Exception):def __init__(self, code, message):self.code = codeself.message = messagetry: # raise MyException()raise 1/0# raiseexcept MyException as e:print('catch my exception')except Exception as e:print(e)print('=== end ===')Out:division by zero=== end ===

6.3 示例 3

f = Nonetry:f = open('111.txt')except Exception as e:print(e.__class__, e.errno, e.strerror)finally:print('clear working')try:f.close()except Exception as e:print(e)Out:<class 'FileNotFoundError'> 2 No such file or directoryclear working'NoneType' object has no attribute 'close'

6.4 示例 4

# 函数的返回值取决于最后一个执行的return语句,而finally则是try...finally中最后执行的语句块def foo():# return 1try:return 3finally:return 5print('Finally')print('===')print(foo())Out:5

6.5 示例 5

try:ret = 1/0# ret = 1 * 0except ArithmeticError as e:print(e)else:print('OK')finally:print('fin')

division by zerofin

6.6 示例 6

try:# ret = 1/0ret = 1 * 0except ArithmeticError as e:print(e)else:print('OK')finally:print('fin')

OKfin

7、异常的传递

7.1 示例 1

foo2调用了foo1foo1产生的异常,传递到了foo2

异常总是向外层抛出,如果外层没有处理这个异常,就会继续向外抛出

如果内层捕获并处理了异常,外部就不能捕获到了

如果到了最外层还是没有被处理,就会中断异常所在的线程的执行

注意整个程序结束的状态返回值

def foo1():return 1/0def foo2():print('foo2 start')foo1()print('foo2 stop')foo2()

D:\PycharmProjects\pythonProject\08089\venv\Scripts\python.exe D:/PycharmProjects/pythonProject/08089/test6.pyTraceback (most recent call last):... ...return 1/0ZeroDivisionError: division by zerofoo2 startProcess finished with exit code 1

7.2 示例 2

# 线程中测试异常import threadingimport timedef foo1():return 1/0def foo2():time.sleep(3)print('foo2 start')foo1()print('foo2 stop')t = threading.Thread(target=foo2)t.start()while True:time.sleep(1)print('Everything is OK.')print(threading.enumerate())

8、try语句

8.1try语法

try:<语句> # 运行别的代码except <异常类>:<语句> # 捕获某种类型的异常except <异常类> as <变量名>:<语句> # 捕获某种类型的异常并获得对象else:<语句> # 如果没有异常发生finally:<语句> # 退出try时总会执行

8.2try工作原理

1 如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句2 如果try中语句执行时发生异常,却没有匹配的except的子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递。如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程3 如果在try执行时没有发生异常,如有else子句,可执行else子句中的语句4 无论try中是否发生异常,finally子句最终都会执行

8.3 示例 1

# try嵌套# 内部捕获不到异常,会向外层传递异常# 但是如果函数内层有finally且其中有return break语句,则异常就不会继续向外抛出try:try:ret = 1/0except KeyError as e:# except ZeroDivisionError as e:print(e)finally:print('inner fin')except:print('outer catch')finally:print('outer fin')

inner finouter catchouter fin

8.4 示例 2

# try嵌套# 内部捕获不到异常,会向外层传递异常# 但是如果函数内层有finally且其中有return break语句,则异常就不会继续向外抛出def foo():try:ret = 1/0except KeyError as e:print(e)finally:print('inner fin')returntry:foo()except:print('outer catch')finally:print('outer fin')

inner finouter fin

9、异常的捕获时机

1 立即捕获:需要立即返回一个明确的结果

2 边界捕获:封装产生了边界

def parse_int(s):try:return int(s)except:return 0print(parse_int('s'))Out:0

10、自定义异常类注意事项

10.1 异常类写的有问题

# 自己写的异常类没写对,抛出异常,被exception捕获class MyException(Exception):def __init__(self, code, msg):self.code = codeself.msg = msgtry:raise MyException # 抛出的异常都是实例except NotImplementedError as e:print('not imp', e, type(e))except MyException as e:print('my exception', e, type(e))except Exception as e:print('all exception', e, type(e))print('end')

all exception __init__() missing 2 required positional arguments: 'code' and 'msg' <class 'TypeError'>end

10.2 异常类传入参数

class MyException(Exception):def __init__(self, code, msg):self.code = codeself.msg = msgtry:raise MyException(999, '123')except NotImplementedError as e:print('not imp', e, type(e))except MyException as e:print('my exception', e, type(e))except Exception as e:print('all exception', e, type(e))print('end')

my exception (999, '123') <class '__main__.MyException'>end

10.3 异常类传入默认参数

class MyException(Exception):def __init__(self, code="200", msg="Not OK"):self.code = codeself.msg = msgtry:raise MyException # 等效于raise MyException()except NotImplementedError as e:print('not imp', e, type(e))except MyException as e:print('my exception', e, type(e), e.code)except Exception as e:print('all exception', e, type(e))print('end')

my exception <class '__main__.MyException'> 200end

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。