Python中的异常处理
Posted PiaYie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python中的异常处理相关的知识,希望对你有一定的参考价值。
Python中的异常事件:
当Python遇到无法正常处理的事件时,便是异常发生的时候,Python将异常也当作一个对象,尽管他是出错的。当发生异常时候我们要捕获他,否则程序就会中断运行。
Python标准异常:
异常名称 | 说明 |
NameError | 语法错误,未声明/初始化对象 (没有属性) |
EOFError | 用户输入文件末尾标志EOF(Ctrl+d),Python3.2无 |
AssertionError | 断言语句(assert)失败 |
KeyboardInterrupt | 用户输入中断键(Ctrl+c) |
KeyError | 字典中查找一个不存在的关键字 |
ValueError | 传入无效的参数 |
ZeroDivisionError | 除数为零 |
AttributeError | 尝试访问未知的对象属性 |
FloatingPointError | 浮点计算错误 |
GeneratorExit | generator.close()方法被调用的时候 |
ImportError | 导入模块失败的时候 |
IndexError | 索引超出序列的范围 |
MemoryError | 内存溢出(可通过删除对象释放内存) |
NotImplementedError | 尚未实现的方法 |
OSError | 操作系统产生的异常(例如打开一个不存在的文件) |
OverflowError | 数值运算超出最大限制 |
StopIteration | 迭代器没有更多的值 |
RuntimeError | 一般的运行时错误 |
SyntaxError | Python的语法错误 |
IndentationError | 缩进错误 |
SystemError | Python编译器系统错误 |
SystemExit | Python编译器进程被关闭 |
TypeError | 不同类型间的无效操作 |
UnboundLocalError | 访问一个未初始化的本地变量(NameError的子类) |
UnicodeError | Unicode相关的错误(ValueError的子类) |
UnicodeEncodeError | Unicode编码时的错误(UnicodeError的子类) |
UnicodeDecodeError | Unicode解码时的错误(UnicodeError的子类) |
UnicodeTranslateError | Unicode转换时的错误(UnicodeError的子类) |
Python内置异常类的层次结构:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- 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
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
Python错误处理方法:
不处理
中断程序,并在终端显示异常信息。
处理异常
我们可以使用try...except语句来处理异常,常把通常的语句放在try-块中,把异常处理语句放在except-块中。
把所有可能引发错误的语句放在 try 块中,然后在 except 从句/块中处理所有 的错误和异常
1 try: 2 <statements> #运行try语句块,并试图捕获异常 3 except <name1>: 4 <statements> #如果name1异常发现,那么执行该语句块。 5 except (name2, name3): 6 <statements> #如果元组内的任意异常发生,那么捕获它 7 except <name4> as <variable>: 8 <statements> #如果name4异常发生,那么进入该语句块,并把异常实例命名为variable 9 except: 10 <statements> #发生了以上所有列出的异常之外的异常 11 else: 12 <statements> #如果没有异常发生,那么执行该语句块 13 finally: 14 <statement> #无论是否有异常发生,均会执行该语句块。
注意,
else和finally是可选的;
except从句可以专门处理单一错误或者异常,也可以处理一组包括在圆括号里面的异常;
如果except没有指定错误名称,即:
1 except: 2 #处理除了上述提到的以外的异常和错误
对于每个try语句,至少有一个相关联的except从句;
如果某个错误或异常没有被处理,默认的 Python 处理器就会被调用。它会终止 程序的运行,并且打印一个消息;
引发异常
使用raise语句来主动引发异常,需要指明1.异常的名称、2.伴随异常触发的异常对象(描述信息)。
可以引发的错误或异常应该分别是一个 Error 或 Exception 类的直接或间接导出类。
raise的基本语法格式为:
raise [exceptionName [(reason)]]
注意exceptionName和(reason)都是可选的。每次执行 raise 语句,都只能引发一次执行的异常。
1、如果不带任何参数,单独一个raise,即
raise:#该语句引发当前上下文中捕获的异常
2、指明异常的名称
raise exceptionName #raise 后带一个异常类名称,表示引发执行类型的异常。
3、指明异常的名称、伴随信息
raise exceptionName("除数不能为零")#引发特定类型异常的同时,附加异常描述信息
raise ShortInputException(len(text),3)
用户自定义异常
显然自己定义的异常类需要直接或者间接继承自Exception类。
#1.用户自定义异常类型 class TooLongExceptin(Exception): "this is user‘s Exception for check the length of name " def __init__(self,leng): self.leng = leng def __str__(self): print("姓名长度是"+str(self.leng)+",超过长度了") #2.手动抛出用户自定义类型异常 def name_Test(): name = input("enter your naem:") if len(name)>4: raise TooLongExceptin(len(name)) #抛出异常很简单,使用raise即可,但是没有处理,即捕捉 else : print(name) #调用函数,执行 name_Test()
运行结果:
Traceback (most recent call last): File "d:PiaYieVScodepython学习笔记hello.py", line 49, in <module> name_Test() File "d:PiaYieVScodepython学习笔记hello.py", line 44, in name_Test raise TooLongExceptin(len(name)) #抛出异常很简单,使用raise即可,但是没有处理,即捕捉 __main__.TooLongExceptin姓名长度是6,超过长度了 : <exception str() failed>
值得一提的是,主动地引发异常,我们的目的并不是让自己的程序挂机,raise语句引发异常常使用try...excep语句来捕获并进行处理,使得程序更加优雅。
例如:
1 try: 2 a = input("输入一个数:") 3 #判断用户输入的是否为数字 4 if(not a.isdigit()): 5 raise ValueError("a 必须是数字") 6 except ValueError as e: 7 print("引发异常:",repr(e))
运行结果:
输入一个数:l 引发异常: ValueError(‘a 必须是数字‘)
try...finally语句
上面已经提到,finally是可选的,如果存在该语句块,无论是否有异常发生,均会执行该语句块。
1 import time 2 3 try: 4 f = open(‘poem.txt‘) 5 while True: # our usual file-reading idiom 6 line = f.readline() 7 if len(line) == 0: 8 break 9 print(line, end = ‘‘) 10 time.sleep(2) # To make sure it runs for a while 11 except KeyboardInterrupt: 12 print(‘!! You cancelled the reading from the file.‘) 13 finally: 14 f.close() 15 print(‘(Cleanig up: closed the file)‘) 16
运行结果:
123 546 79a !! You cancelled the reading from the file. (Cleanig up: closed the file) D:PiaYieVScodepython学习笔记>
读文件时,每打印一行停顿两秒钟,可以让程序运行的更慢一些,按Ctrl+C中断阅读便发生KeyboardInterrupt异常并且被捕获。
我们习惯在 try 块中获得资源,随后又在 ?nally 块中释放资源。还有一种with...as语句也能完成这样的功能。
with...as语句
1 with open("poem.txt") as f: 2 for line in f: 3 print(line,end=‘‘)
输出:
123
546
79a
sad
dsad
asdsasdasda
sdasd
asd
D:PiaYieVScodepython学习笔记>
with 语句使用 open 函数 —— 用 with open 就能使得在结束的时候自动关闭文件。这是因为with 语句使用了一种协议。获得了 open 语句返回的对象the_obj,在启动代码块之前,在后台总会调用 the_obj.__enter__ 函数,在代码块结束后又 会调用 the_obj.__exit__ 函数。
显然这种自动的方法可以避免使用显示的try...finally语句。
以上是关于Python中的异常处理的主要内容,如果未能解决你的问题,请参考以下文章