一.简介
Python有两种错误很容易辨认:语法错误和异常
语法错误
错误是指语法或者是逻辑上的。语法错误指示软件的结构上的错误,导致不能被解释器或者编译器无正常解析或编译
如:
>>> while True: ... print("a") ... break File "<stdin>", line 3 break ^ SyntaxError: invalid syntax
2.异常
异常是因程序 出现了错误而在正常控制流以外采取的行为。大多数的异常都不会被程序处理,都以错误信息的形式展现
常见异常
- NameError #尝试访问一个未声明的变量
- ZeroDivisionError #除数为零
- SyntaxError #python解释器语法错误
- IndexError #请求的索引超出序列范围
- KeyError #请求一个不存在的字典关键字
- IOError #输入/输出错误
- AttributeError #尝试访问未知的对象属性
- keyboardInterrupt #用户中断执行(^c)
- IndentationError #缩进错误
- TypeError #对类型无效的操作
- ValueError #传入无效的参数
- DeprecationWarning #关于被弃用的特征警告
- ArithmeticError #所有数值计算错误的基类
- SystemExit #解释器请求退出
- ImportError #导入模块/对象失败
- MemoryError #内存溢出
二.检测和处理异常
异常可通过try语句来检测,任何在try语句块里的代码都会被监测,检查有无异常发生
try语句主要有两种形式:try-except 和 try-finally
一个try语句可以对应一个或者多个except子句,但只能对应一个finally子句,或是一个try-execpt-finally复合语句
可以使用try-except语句检测和处理异常,也可以添加一人可选的else子句处理没有探测到异常的执行代码。
而try-finally只允许检测异常并做出一些必要的清除工作(无论发生错误与否),没有任何异常处理的设施
try语句按照如下方式工作:
-
- 首先,执行try子句(在关键字try和关键字except之间的语句)
- 如果没有异常发生,忽略except子句,try子句执行后结束。
- 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
- 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中
execpt基本语法
try: do something except Exception[,reason]: suite_for_exception_Exception
如:
inp = input("num:") try: num = int(inp) print(num) except Exception as e: print("转换失败")
try except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后.这个子句将在try子句没有发生任何异常的时候执行。例如:
inp = input("num:") try: num = int(inp) print(num) except Exception as e: print("转换失败") else: print("成功")
带有多个except的try语句
li = [] inp = input("num:") try: num = li[inp] except IndexError as I: print(I) except Exception as e: print(e)
捕获所有异常
Exception
li = [] inp = input("num:") try: num = li[inp] #Exception捕获所有异常 except Exception as e: print(e)
主动触发异常
#主动触发 try: print("123") raise Exception("error...") except Exception as e: print(e)
用户自定义异常
创建一个新的exception类来拥有自己的异常。异常应该继承自 Exception 类,或者直接继承,或者间接继承
class Foo(): def __init__(self,name): self.Name = name def __str__(self): return self.Name obj = Foo("test") print(obj)
2 finally子句
finally子句是无论异常与否,是否捕捉到都会执行的一段代码。语法结构
try: A except: B else: C finally: D
无论异常发生在A,B,C最终都会执行D
3 try-finally语句
另一种使用finally的方式finally单独和try连用,它和try-except区别在于它不是用来捕捉异常的
它常常用来给维护一致的行为而无论异常是否发生。finally代码段都将被执行
def change_pwd(username, password): """ 用户修改密码 :param username: 用户名 :param password: 修改后的密码 :return: True修改成功,False修改失败 """ file_object = open('log') try: lines=open('log','r').readlines() for i in range(len(lines)): if username in lines[i]: test=lines[i].split('$')[1] lines[i]=lines[i].replace(test,password) open('log','w').writelines(lines) return True return False finally: file_object.close( )
三.触发异常
1.raise语句
raise语句对所支持的参数十分灵活,对应到语法上就是支持许多不同的格式,raise一般用法是
raise [SomeException,[, args [, traceback]]]
- SomeException 触发异常的名字,如果有它必须是一个字符串,类或实例
- args 可选的args(比如参数值)来传送给异常,可以是单独的对象或者对象的元组
- traceback 可选参数 (很少使用),当异常触发时新生成一个用于异常--正常化的跟踪记录对象
2.raise语句用法
raise exclass #触发一个异常,从exclass生成一个实例(不含任何异常参数)、
raise exclass() #通过函数调用操作符(function calloperator:())作用于类名乱一个新的exclass实例,同样没有参数
raise exclass,args #同上,但同时提供异常参数args,可以是一个参数也可以是一个元组
raise exclass,instance #通过实例触发异常,如果 实例是exclass的子类实例,那么新导演类型会是子类类型,如果 不是也会会是exclass子类,会复制生成新的exclass实例
例
try: 正常逻辑 except "Invalid level!": 触发自定义异常 else: 其余代码
#!/usr/bin/python # -*- coding: UTF-8 -*- # 定义函数 def myexce( level ): if level < 1: raise Exception("Invalid level!", level) # 触发异常后,后面的代码就不会再执行 try: myexec(0) // 触发异常 except "Invalid level!": print 1 else: print 2