异常之异常处理
异常介绍
异常是程序发生错误的信号。程序一旦出现错误,便会产生一个异常,若程序中没有处理它,就会抛出该异常,程序的运行也随之终止。
异常的作用是: 为了增强程序的健壮性, 即便是程序运行过程出错了, 也不要终止程序, 而是应该捕捉异常并处理: 将出错信息记录到日志内
错误的类型一共有两种:
一种是语法错误, SyntaxError, 必须在程序运行前就改正; 另一种是逻辑错误
针对逻辑上的异常又分为两种处理方式
错误发生的条件是可以预知的: 使用if判断来解决
age = input('>>: ').strip() # 输入的只要不是数字就会出错 if age.isdigit(): age = int(age) if age > 18: print('成年') else: print('未成立') else: print('必须输入数字') """
错误发生的条件是无法预知的: 那么可以使用try语法来解决
异常的抛出机制:
1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler).
2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。
3、如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因。
异常处理
我们可以通过使用 try..except 来处理异常状况。一般来说我们会把通常的语句放在 try 代码块中,将我们的错误处理器代码放置在 except 代码块中。
try: 子代码块 # 有可能会抛出异常的代码 except 异常类型1 as e: pass except 异常类型2 as e: pass ... else: # else不能单独与try连用, 必须要加except 如果被检测的子代码块没有异常发生, 则会执行else的子代码块 finally: # finally可以单独与try连用 无论被检测的代码块有无异常发生, 都会执行finally的子代码
需要注意的是, 如果try中捕获了异常, 那么就会执行except中的语句, 被检测的子代码块没有异常发生, 那么会执行else的子代码块, else不能与try单独连用, 会报语法错误。不管有没有异常发生, 都可以运行finally中的代码, 可以使用finally代码执行一些需要回收系统资源的代码。当然, finally可以与try单独连用
print('start...') try: l = ['aaa', 'bbb'] print(l[3]) # 抛出异常IndexError, 该行代码的后续代码不会运行 # except IndexError as e: except (IndexError, NameError) as e: print('异常信息:', e) except KeyError as e: print('异常信息:', e) except Exception as e: # 万能异常 print('所有异常都能匹配的上') else: print('---------------->') finally: print('应该把被检测代码中回收系统资源的代码放到这里') print('end...')
- 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
- 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
- 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
- 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
- 使用Exception可以捕获任何异常
Python内置异常类
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 # 与资源使用相关的警告的基类。被默认警告过滤器忽略。