寂寞是一种心情,孤独是一种人生!

try的工作原理
- 如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句
- 如果try中语句执行时发生异常,却没有匹配的except子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递。如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程;
- 如果在try执行时没有发生异常,将执行else子句中的语句
- 无论try中是否发生异常,finally子句最终都会执行
推出
捕获异常避免意外;
1. 异常类及继承层次
在Python中,异常也是对象,可对它进行操作。BaseException是所有内置异常的基类,但用户定义的类并不直接继承BaseException,所有的异常类都是从Exception继承,且都在exceptions模块中定义。Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。
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 # 与资源使用相关的警告的基类。被默认警告过滤器忽略。
KeyboardInterrupt
对应的捕获键盘Ctrl + C,中断行为
BaseException及子类
BaseException
所有内建异常类的基类是BaseException
SystemExit
sys.exit()函数引发的异常,异常不捕获处理,就直接交给Python解释器,解释器节退出;
import sys
print('before')
sys.exit(1)
print('SysExit')
print('outer') # 是否执行?
# 捕获这个异常
import sys
try:
sys.exit(1)
except SystemExit: # 换成Exception
print('SysExit')
print('outer') # 是否执行?
如果except语句捕获了该异常,则继续向后面执行,如果没有捕获住该异常SystemExit,解释器直接退出程序。
KeyboardInterrupt
对应的捕获用户中断行为Ctrl + C
try:
import time
while True:
time.sleep(0.5)
pass
except KeyboardInterrupt:
print('ctl + c')
print('outer')
Exception及子类
Exception是所有内建的、非系统退出的异常的基类,自定义异常应该继承自它
SyntaxError 语法错误
Python将这种错误也归到异常类下面的Exception下的子类,但是这种错误是不可捕获的;
ArithmeticError
所有算术引发的异常,其子类有除零异常等;
LookupError
使用映射的键或序列的索引无效时引发的异常的基类:IndexError, KeyError
自定义异常
从Exception继承的类
2. 捕获规则
捕获是从上到下依次比较 从小到大,从具体到宽泛;
如果匹配,则执行匹配的except语句块
如果被一个except语句捕获,其他except语句就不会再次捕获了
如果没有任何一个except语句捕获到这个异常,则该异常向外抛出
class MyException(Exception):
pass
try:
a = 1/0 #
raise MyException() # 自定义
open('a1.txt') #
except MyException:
print('catch the MyException')
except ZeroDivisionError:
print('1/0')
except Exception: # 调整except的顺序
print('Exception')
# f 不存在的情况下异常 怎么处理(先赋值为None)
f = None
try:
f = open('test.txt')
except Exception as e:
print('{}'.format(e))
finally:
print('清理工作')
if f:
f.close()
3. try异常嵌套
内部捕获不到异常,会向外层传递异常
但是如果内层有finally且其中有return、break语句,则异常就不会继续向外抛出
try:
try:
ret = 1 / 0
except KeyError as e:
print(e)
finally:
print('inner fin')
except:
print('outer catch')
finally:
print('outer fin')
4. 异常的捕获时机
1、立即捕获
需要立即返回一个明确的结果
# 整数转换 返回一个结果
def parse_int(s):
try:
return int(s) # 要么转换;
except:
return 0 # 不能转换返回一个结果0;
print(parse_int('s'))
2、边界捕获
封装产生了边界。
例如,写了一个模块,用户调用这个模块的时候捕获异常,模块内部不需要捕获、处理异常,一旦内部处理了,外部调用者就无法感知了。
例如,open函数,出现的异常交给调用者处理,文件存在了,就不用再创建了,看是否修改还是删除
例如,自己写了一个类,使用了open函数,但是出现了异常不知道如何处理,就继续向外层抛出,一般来说最外层也是边界,必须处理这个异常了,否则线程退出
else子句:没有任何异常则执行;
总结:
最复杂的也不过如此;
try:
<语句> #运行别的代码
except <异常类>:
<语句> # 捕获某种类型的异常;
except <异常类> as <变量名>:
<语句> # 捕获某种类型的异常并获得对象;
else: # 使用相对较少;
<语句> # 如果没有异常发生
finally:
<语句> #退出try时总会执行
try的工作原理
- 如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句
- 如果try中语句执行时发生异常,却没有匹配的except子句,异常将被递交到外层的try,如果外层不处理这个异常,异常将继续向外层传递。如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在的线程;
- 如果在try执行时没有发生异常,将执行else子句中的语句
- 无论try中是否发生异常,finally子句最终都会执行
网友评论