- Python的异常处理能力是很强大的,它有很多内置异常,可向用户准确反馈出错信息。-
- 在Python中,异常也是对象,可对它进行操作。BaseException是所有内置异常的基类,但用户定义的类并不直接继承BaseException,所有的异常类都是从Exception继承,且都在exceptions模块中定义。
- Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。
- 一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。
异常处理结构
try-except 语句
try:
正常的操作
......................
except:
发生异常,执行这块代码
......................
else:
如果没有异常执行这块代码
try-finally 语句
try-finally 语句无论是否发生异常都将执行最后的代码。
try:
<语句>
finally:
<语句> #退出try时总会执行
raise
合体
try:
# 可能发生异常的代码
except 异常类型1 as 变量名:
print(变量名) # 变量名存储的是具体的错误信息
except 异常类型2 as 变量名:
print(变量名) # 变量名存储的是具体的错误信息
except Exception as 变量名:
print(变量名) # 变量名存储的是具体的错误信息
else:
print('如果以上代码没有发生异常以及异常处理工作就执行这里的代码')
print('一般情况下else中的代码用来下结论')
# logging模块
finally:
print('不管代码是否有异常都会执行,且在函数中遇到return仍然会执行')
print('一般情况下用于这个函数中资源的回收')
捕获异常
常见异常 | |
---|---|
AttributeError | 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x |
IOError | 输入/输出异常;基本上是无法打开文件 |
ImportError | 无法引入模块或包;基本上是路径问题或名称错误 |
IndentationError | 语法错误(的子类) ;代码没有正确对齐 |
IndexError | 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] |
KeyError | 试图访问字典里不存在的键 |
KeyboardInterrupt | Ctrl+C被按下 |
NameError | 使用一个还未被赋予对象的变量 |
SyntaxError | Python代码非法,代码不能编译(个人认为这是语法错误,写错了) |
TypeError | 传入对象类型与要求的不符合 |
UnboundLocalError | 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它 |
ValueError | 传入一个调用者不期望的值,即使值的类型是正确的 |
捕获多个异常
try:
<语句>
except <异常名1>:
print('异常说明1')
except <异常名2>:
print('异常说明2')
except <异常名3>:
print('异常说明3')
该种异常处理语法的规则是:
- 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
- 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
- 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
- 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
案例解析
def func() :
try:
n1 = int(input('输入第一个数字:'))
n2 = int(input('输入第二个数字:'))
per = input('输入运算符号(+一* /):')
result= 0
if per == '+':
result = n1+ n2
elif per == '-':
result = n - n2
elif per == '*':
result = n1 * n2
elif per == '/':
result = n1 / n2
else:
print('符号输入有误!')
print('结果是:',sum)
#文件操作
with open(r'c:\p1\aa2.txt’,'w') as wstream:
wstream. write("本次的运算结果是: {}".format(result))
except ZeroDivisionError:
print('除数不能为零! ! ! !')
except ValueError :
print('必须输入数字!!!!')
except FileNotFoundError:
print('文件错误')
except NameError :
print('名称错误')
except Excention:
print('出错了')
捕获所有异常
try:
<语句>
except Exception:
print('异常说明')
自定义异常
raise 语句的基本语法格式为:
raise [exceptionName [(reason)]]
- 其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。
- 如果可选参数全部省略,则 raise会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。
raise 语句三种常用的用法:
- raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
- raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
- raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
注册用户名必须6位
def register():
username = input('输入用户名:')
if len(username) < 6:
raise Exception('用户长度必须6位以上')
else :
print('输入的用户名是:',username)
try :
register()
except Exception as err:
print (err)
print('注册失败!’ )
else:
print('注册成功! ')
扩展
异常层级关系
BaseException # 所有异常的基类
+-- SystemExit # 解释器请求退出
+-- KeyboardInterrupt # 用户中断执行(通常是输入^C)
+-- GeneratorExit # 生成器(generator)发生异常来通知退出
+-- Exception # 常规异常的基类
+-- StopIteration # 迭代器没有更多的值
+-- StopAsyncIteration # 必须通过异步迭代器对象的__anext__()方法引发以停止迭代
+-- ArithmeticError # 各种算术错误引发的内置异常的基类
| +-- FloatingPointError # 浮点计算错误
| +-- OverflowError # 数值运算结果太大无法表示
| +-- ZeroDivisionError # 除(或取模)零 (所有数据类型)
+-- AssertionError # 当assert语句失败时引发
+-- AttributeError # 属性引用或赋值失败
+-- BufferError # 无法执行与缓冲区相关的操作时引发
+-- EOFError # 当input()函数在没有读取任何数据的情况下达到文件结束条件(EOF)时引发
+-- ImportError # 导入模块/对象失败
| +-- ModuleNotFoundError # 无法找到模块或在在sys.modules中找到None
+-- LookupError # 映射或序列上使用的键或索引无效时引发的异常的基类
| +-- IndexError # 序列中没有此索引(index)
| +-- KeyError # 映射中没有这个键
+-- MemoryError # 内存溢出错误(对于Python 解释器不是致命的)
+-- NameError # 未声明/初始化对象 (没有属性)
| +-- UnboundLocalError # 访问未初始化的本地变量
+-- OSError # 操作系统错误,EnvironmentError,IOError,WindowsError,socket.error,select.error和mmap.error已合并到OSError中,构造函数可能返回子类
| +-- BlockingIOError # 操作将阻塞对象(e.g. socket)设置为非阻塞操作
| +-- ChildProcessError # 在子进程上的操作失败
| +-- ConnectionError # 与连接相关的异常的基类
| | +-- BrokenPipeError # 另一端关闭时尝试写入管道或试图在已关闭写入的套接字上写入
| | +-- ConnectionAbortedError # 连接尝试被对等方中止
| | +-- ConnectionRefusedError # 连接尝试被对等方拒绝
| | +-- ConnectionResetError # 连接由对等方重置
| +-- FileExistsError # 创建已存在的文件或目录
| +-- FileNotFoundError # 请求不存在的文件或目录
| +-- InterruptedError # 系统调用被输入信号中断
| +-- IsADirectoryError # 在目录上请求文件操作(例如 os.remove())
| +-- NotADirectoryError # 在不是目录的事物上请求目录操作(例如 os.listdir())
| +-- PermissionError # 尝试在没有足够访问权限的情况下运行操作
| +-- ProcessLookupError # 给定进程不存在
| +-- TimeoutError # 系统函数在系统级别超时
+-- ReferenceError # weakref.proxy()函数创建的弱引用试图访问已经垃圾回收了的对象
+-- RuntimeError # 在检测到不属于任何其他类别的错误时触发
| +-- NotImplementedError # 在用户定义的基类中,抽象方法要求派生类重写该方法或者正在开发的类指示仍然需要添加实际实现
| +-- RecursionError # 解释器检测到超出最大递归深度
+-- SyntaxError # Python 语法错误
| +-- IndentationError # 缩进错误
| +-- TabError # Tab和空格混用
+-- SystemError # 解释器发现内部错误
+-- TypeError # 操作或函数应用于不适当类型的对象
+-- ValueError # 操作或函数接收到具有正确类型但值不合适的参数
| +-- UnicodeError # 发生与Unicode相关的编码或解码错误
| +-- UnicodeDecodeError # Unicode解码错误
| +-- UnicodeEncodeError # Unicode编码错误
| +-- UnicodeTranslateError # Unicode转码错误
+-- Warning # 警告的基类
+-- DeprecationWarning # 有关已弃用功能的警告的基类
+-- PendingDeprecationWarning # 有关不推荐使用功能的警告的基类
+-- RuntimeWarning # 有关可疑的运行时行为的警告的基类
+-- SyntaxWarning # 关于可疑语法警告的基类
+-- UserWarning # 用户代码生成警告的基类
+-- FutureWarning # 有关已弃用功能的警告的基类
+-- ImportWarning # 关于模块导入时可能出错的警告的基类
+-- UnicodeWarning # 与Unicode相关的警告的基类
+-- BytesWarning # 与bytes和bytearray相关的警告的基类
+-- ResourceWarning # 与资源使用相关的警告的基类。被默认警告过滤器忽略。
requests模块内置异常类的层次结
IOError
+-- RequestException # 处理不确定的异常请求
+-- HTTPError # HTTP错误
+-- ConnectionError # 连接错误
| +-- ProxyError # 代理错误
| +-- SSLError # SSL错误
| +-- ConnectTimeout(+-- Timeout) # (双重继承,下同)尝试连接到远程服务器时请求超时,产生此错误的请求可以安全地重试。
+-- Timeout # 请求超时
| +-- ReadTimeout # 服务器未在指定的时间内发送任何数据
+-- URLRequired # 发出请求需要有效的URL
+-- TooManyRedirects # 重定向太多
+-- MissingSchema(+-- ValueError) # 缺少URL架构(例如http或https)
+-- InvalidSchema(+-- ValueError) # 无效的架构,有效架构请参见defaults.py
+-- InvalidURL(+-- ValueError) # 无效的URL
| +-- InvalidProxyURL # 无效的代理URL
+-- InvalidHeader(+-- ValueError) # 无效的Header
+-- ChunkedEncodingError # 服务器声明了chunked编码但发送了一个无效的chunk
+-- ContentDecodingError(+-- BaseHTTPError) # 无法解码响应内容
+-- StreamConsumedError(+-- TypeError) # 此响应的内容已被使用
+-- RetryError # 自定义重试逻辑失败
+-- UnrewindableBodyError # 尝试倒回正文时,请求遇到错误
+-- FileModeWarning(+-- DeprecationWarning) # 文件以文本模式打开,但Requests确定其二进制长度
+-- RequestsDependencyWarning # 导入的依赖项与预期的版本范围不匹配
Warning
+-- RequestsWarning # 请求的基本警告