什么是异常
异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止)。
在python中,错误触发的异常如下
而错误分成两种
1.语法错误:(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正)
#语法错误示范一 if #语法错误示范二 def test: pass #语法错误示范三 class Foo pass #语法错误示范四 print(haha)
2.逻辑错误:比如用户输入的不合适等一系列错误
#TypeError:int类型不可迭代 for i in 3: pass #ValueError num=input(">>: ") #输入hello int(num) #NameError aaa #IndexError l=['egon','aa'] l[3] #KeyError dic={'name':'egon'} dic['age'] #AttributeError class Foo:pass Foo.x #ZeroDivisionError:无法完成计算 res1=1/0 res2=1+'str
异常的种类
在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,一个异常标识一种错误
所有错误类型都继承自BaseException
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
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 | 用户代码生成的警告 |
异常处理
为了保证程序的健壮性与容错性,即在遇到错误时程序不会崩溃,我们需要对异常进行处理,
如果错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防
while True: age=input('>>: ').strip() if age.isdigit(): # 只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的 age=int(age) if age > 18: print('you are adult') break
如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理
def sum(n): c = 0 i = 1 while i < n+1: print('{} += {}'.format(c, i)) c += i yield c i += 1 f = sum(10) while True: try: print(next(f)) except StopIteration as e: print('Generator return value:', e.value) break
try..except...详细用法
try: suite1 #测试语句块 except exception1: suite2 #如果测试语句suite1中发生exception1异常时执行 except (exception2,exception3): suite3 #如果测试语句suite1中发生元组中任意异常时执行 except exception4 as reason: #as把异常的原因赋值给reason suite4 #如果测试语句suite1发生exception4的异常时执行 except: suite5 #如果测试语句suite1发生异常在所列出的异常之外时执行 else: suite5 #如果测试语句块suite1中没有发生异常时执行 finally: suit6 #不管测试语句suite1中又没有发生异常都会执行 ''' 注意:中间的except,else,finally都是可选的,但至少有一个,不然try就没有意义了,根据实际中的需求来选择。 '''
1.异常类只能用来处理指定的异常情况,如果非指定异常则无法处理
s1 = 'hello' try: int(s1) except IndexError as e: # 未捕获到异常,程序直接报错 print e
2.多分支
s1 = 'hello' try: int(s1) except IndexError as e: print(e) except KeyError as e: print(e) except ValueError as e: print(e)
3.万能异常Exception
s1 = 'hello' try: int(s1) except Exception as e: print(e)
4.也可以在多分支后来一个Exception
s1 = 'hello' try: int(s1) except IndexError as e: print(e) except KeyError as e: print(e) except ValueError as e: print(e) except Exception as e: print(e)
5.主动触发异常
a = 10 if a < 18: raise ValueError('值错误')
6.如果抛出父类异常,在子类不会再获取
#注意:如果抛出父类异常,在子类不会再获取,如下: try: fun() except Exception as e: raise Exception except ImportError as e: raise ImportError finally: pass ''' 在上面的例子中,下面的ImportError就不会被抛出,应为ImportError继承Exception,但是可以把Exception放在后面是可以的 e可以得到系统给出的报错信息 '''
7.自定义异常
class MyException(BaseException): def __init__(self,msg): super().__init__() self.msg = msg def __str__(self): return self.msg a =88 if a>10: raise MyException('抛出我的异常') class Networkerror(RuntimeError): def __init__(self, msg): self.msg = msg try: raise Networkerror("Bad hostname") except Networkerror as e: print(e)
8.断言:assert 条件
''' 测试表示式,其返回值为假,就会触发异常 ''' assert 1==1 #没有返回值 assert 1<2 #没有返回值 assert 1==2 #返回AssertionError
9.总结异常
1:把错误处理和真正的工作分开来
2:代码更易组织,更清晰,复杂的工作任务更容易实现;
3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;