比如我们要打开一个不存在的文件,它会报错
f=open('no.txt','r') f.read() ''' --------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-54-2709fabe0da7> in <module> ----> 1 f=open('no.txt','r') 2 f.read() FileNotFoundError: [Errno 2] No such file or directory: 'no.txt' '''
我们可以用try-except 实现
try: f=open('no.txt','r') print(f.read()) except FileNotFoundError as e: print(e) f=open('no.txt','w') f.write('new file') f.close() ''' [Errno 2] No such file or directory: 'no.txt' '''
但是如果我们except里面使用了不匹配的error 还是会报错
try: f=open('no1.txt','r') print(f.read()) except KeyError as e: print(e) f=open('no1.txt','w') f.write('new file') f.close() ''' --------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-56-5e0e21b6da44> in <module> 1 try: ----> 2 f=open('no1.txt','r') 3 print(f.read()) 4 except KeyError as e: 5 print(e) FileNotFoundError: [Errno 2] No such file or directory: 'no1.txt' '''
解决方法是使用基类Error
try: f=open('no1.txt','r') print(f.read()) except BaseException as e: print(e) f=open('no1.txt','w') f.write('new file') f.close()
d = {"name": "f1", "age": 2} l = [1,2,3] try: v = d["gender"] l[3] = 4 except KeyError as e: print("key error for:", e) d["gender"] = "x" except IndexError as e: print("index error for:", e) l.append(4) print(d) print(l) ''' key error for: 'gender' {'name': 'f1', 'age': 2, 'gender': 'x'} [1, 2, 3] '''
但是此时有一点需要注意:它不会同时处理字典的 KeyError
和列表的 IndexError
因为在程序顺序执行的时候,只要是报错了, 那么就会终止错误之后的代码,进入错误 回收 环节。这个回收环节在上面的案例中也就是 except
的错误处理环节。
换句话说,except语句只能执行一个。
所以上述例子中,列表l并没有被append
try-except和前面的一样,在 else
中处理没有报错的情况。
l = [1,2,3] try: l[3] = 4 except IndexError as e: print(e) else: print("no error, now in else") print(l) ''' list assignment index out of range ''' #此时是有异常的,所以执行的是except里面的语句 l = [1,2,3,-4] try: l[3] = 4 except IndexError as e: print(e) else: print("no error, now in else") print(l) ''' no error, now in else [1, 2, 3, 4] ''' #此时没有异常,所以执行的是try和else里面的语句
try-except和前面的一样,finally中的语句,不管有没有异常,都会执行
在有些情况下,加不加finally,好像没啥区别
没有异常:
l = [1,2,3,-1] try: l[3] = 4 except IndexError as e: print(e) finally: print("reach finally") ''' reach finally '''l = [1,2,3,-1] try: l[3] = 4 except IndexError as e: print(e) print("reach finally") ''' reach finally '''
有异常:
l = [1,2,3] try: l[3] = 4 except IndexError as e: print(e) print("reach finally") ''' list assignment index out of range reach finally '''l = [1,2,3] try: l[3] = 4 except IndexError as e: print(e) finally: print("reach finally") ''' list assignment index out of range reach finally '''
所以,finally语句什么使用需要用到呢?
我们看下面这个例子:
l = [1,2,3] try: l[3] = 4 print("reach finally") ''' File "<ipython-input-71-5a32d8788477>", line 6 print("reach finally") ^ SyntaxError: invalid syntax ''' l = [1,2,3] try: l[3] = 4 finally: print("reach finally") ''' reach finally --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-75-26ba6fe359fd> in <module> 1 l = [1,2,3] 2 try: ----> 3 l[3] = 4 4 finally: 5 print("reach finally") IndexError: list assignment index out of range '''虽然都是报错,但是加了finally之后,就是先执行完finally中的语句,再报错
手动触发异常
def no_negative(num): if num < 0: raise ValueError("I said no negative") return num print(no_negative(-1)) ''' Traceback (most recent call last): File "/lib/python3.8/asyncio/futures.py", line 178, in result raise self._exception File "/lib/python3.8/asyncio/tasks.py", line 280, in __step result = coro.send(None) File "/lib/python3.8/site-packages/pyodide/_base.py", line 419, in eval_code_async return await CodeRunner( File "/lib/python3.8/site-packages/pyodide/_base.py", line 276, in run_async res = eval(last_expr, self.globals, self.locals) File "<exec>", line 6, in <module> File "<exec>", line 3, in no_negative ValueError: I said no negative '''
注:这里raise 后面的error类型,必须是python 中定义的异常错误类型名称(见第6小节)
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
参考内容:如何控制异常 try-except - 交互式学Python | 莫烦Python (mofanpy.com)